1784 lines · cpp
1//===- unittest/Format/FormatTestObjC.cpp - Formatting unit tests----------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "FormatTestBase.h"10 11#define DEBUG_TYPE "format-test-objc"12 13namespace clang {14namespace format {15namespace test {16namespace {17 18class FormatTestObjC : public FormatTestBase {19protected:20 FormatTestObjC() {21 Style = getLLVMStyle();22 Style.Language = FormatStyle::LK_ObjC;23 }24 25 FormatStyle getDefaultStyle() const override { return Style; }26 27 FormatStyle Style;28};29 30#define verifyIncompleteFormat(...) \31 _verifyIncompleteFormat(__FILE__, __LINE__, __VA_ARGS__)32#define verifyFormat(...) _verifyFormat(__FILE__, __LINE__, __VA_ARGS__)33 34TEST(FormatTestObjCStyle, DetectsObjCInStdin) {35 auto Style = getStyle("LLVM", "<stdin>", "none",36 "@interface\n"37 "- (id)init;");38 ASSERT_TRUE((bool)Style);39 EXPECT_EQ(FormatStyle::LK_ObjC, Style->Language);40}41 42TEST(FormatTestObjCStyle, DetectsObjCInHeaders) {43 auto Style = getStyle("LLVM", "a.h", "none",44 "@interface\n"45 "- (id)init;");46 ASSERT_TRUE((bool)Style);47 EXPECT_EQ(FormatStyle::LK_ObjC, Style->Language);48 49 Style = getStyle("LLVM", "a.h", "none",50 "@interface\n"51 "+ (id)init;");52 ASSERT_TRUE((bool)Style);53 EXPECT_EQ(FormatStyle::LK_ObjC, Style->Language);54 55 Style = getStyle("LLVM", "a.h", "none",56 "@interface\n"57 "@end\n"58 "//comment");59 ASSERT_TRUE((bool)Style);60 EXPECT_EQ(FormatStyle::LK_ObjC, Style->Language);61 62 Style = getStyle("LLVM", "a.h", "none",63 "@interface\n"64 "@end //comment");65 ASSERT_TRUE((bool)Style);66 EXPECT_EQ(FormatStyle::LK_ObjC, Style->Language);67 68 // No recognizable ObjC.69 Style = getStyle("LLVM", "a.h", "none", "void f() {}");70 ASSERT_TRUE((bool)Style);71 EXPECT_EQ(FormatStyle::LK_Cpp, Style->Language);72 73 Style = getStyle("{}", "a.h", "none", "@interface Foo\n@end");74 ASSERT_TRUE((bool)Style);75 EXPECT_EQ(FormatStyle::LK_ObjC, Style->Language);76 77 Style = getStyle("{}", "a.h", "none",78 "const int interface = 1;\nconst int end = 2;");79 ASSERT_TRUE((bool)Style);80 EXPECT_EQ(FormatStyle::LK_Cpp, Style->Language);81 82 Style = getStyle("{}", "a.h", "none", "@protocol Foo\n@end");83 ASSERT_TRUE((bool)Style);84 EXPECT_EQ(FormatStyle::LK_ObjC, Style->Language);85 86 Style = getStyle("{}", "a.h", "none",87 "const int protocol = 1;\nconst int end = 2;");88 ASSERT_TRUE((bool)Style);89 EXPECT_EQ(FormatStyle::LK_Cpp, Style->Language);90 91 Style = getStyle("{}", "a.h", "none", "typedef NS_ENUM(int, Foo) {};");92 ASSERT_TRUE((bool)Style);93 EXPECT_EQ(FormatStyle::LK_ObjC, Style->Language);94 95 Style = getStyle("{}", "a.h", "none", "typedef NS_CLOSED_ENUM(int, Foo) {};");96 ASSERT_TRUE((bool)Style);97 EXPECT_EQ(FormatStyle::LK_ObjC, Style->Language);98 99 Style = getStyle("{}", "a.h", "none", "typedef NS_ERROR_ENUM(int, Foo) {};");100 ASSERT_TRUE((bool)Style);101 EXPECT_EQ(FormatStyle::LK_ObjC, Style->Language);102 103 Style = getStyle("{}", "a.h", "none", R"objc(104NS_ASSUME_NONNULL_BEGIN105extern int i;106NS_ASSUME_NONNULL_END107)objc");108 ASSERT_TRUE((bool)Style);109 EXPECT_EQ(FormatStyle::LK_ObjC, Style->Language);110 111 Style = getStyle("{}", "a.h", "none", R"objc(112FOUNDATION_EXTERN void DoStuff(void);113)objc");114 ASSERT_TRUE((bool)Style);115 EXPECT_EQ(FormatStyle::LK_ObjC, Style->Language);116 117 Style = getStyle("{}", "a.h", "none", R"objc(118FOUNDATION_EXPORT void DoStuff(void);119)objc");120 ASSERT_TRUE((bool)Style);121 EXPECT_EQ(FormatStyle::LK_ObjC, Style->Language);122 123 Style = getStyle("{}", "a.h", "none", "enum Foo {};");124 ASSERT_TRUE((bool)Style);125 EXPECT_EQ(FormatStyle::LK_Cpp, Style->Language);126 127 Style = getStyle("{}", "a.h", "none", "inline void Foo() { Log(@\"Foo\"); }");128 ASSERT_TRUE((bool)Style);129 EXPECT_EQ(FormatStyle::LK_ObjC, Style->Language);130 131 Style = getStyle("{}", "a.h", "none", "inline void Foo() { Log(\"Foo\"); }");132 ASSERT_TRUE((bool)Style);133 EXPECT_EQ(FormatStyle::LK_Cpp, Style->Language);134 135 Style =136 getStyle("{}", "a.h", "none", "inline void Foo() { id = @[1, 2, 3]; }");137 ASSERT_TRUE((bool)Style);138 EXPECT_EQ(FormatStyle::LK_ObjC, Style->Language);139 140 Style = getStyle("{}", "a.h", "none",141 "inline void Foo() { id foo = @{1: 2, 3: 4, 5: 6}; }");142 ASSERT_TRUE((bool)Style);143 EXPECT_EQ(FormatStyle::LK_ObjC, Style->Language);144 145 Style = getStyle("{}", "a.h", "none",146 "inline void Foo() { int foo[] = {1, 2, 3}; }");147 ASSERT_TRUE((bool)Style);148 EXPECT_EQ(FormatStyle::LK_Cpp, Style->Language);149 150 // ObjC characteristic types.151 Style = getStyle("{}", "a.h", "none", "extern NSString *kFoo;");152 ASSERT_TRUE((bool)Style);153 EXPECT_EQ(FormatStyle::LK_ObjC, Style->Language);154 155 Style = getStyle("{}", "a.h", "none", "extern NSInteger Foo();");156 ASSERT_TRUE((bool)Style);157 EXPECT_EQ(FormatStyle::LK_ObjC, Style->Language);158 159 Style = getStyle("{}", "a.h", "none", "NSObject *Foo();");160 ASSERT_TRUE((bool)Style);161 EXPECT_EQ(FormatStyle::LK_ObjC, Style->Language);162 163 Style = getStyle("{}", "a.h", "none", "NSSet *Foo();");164 ASSERT_TRUE((bool)Style);165 EXPECT_EQ(FormatStyle::LK_ObjC, Style->Language);166}167 168TEST(FormatTestObjCStyle, AvoidDetectingDesignatedInitializersAsObjCInHeaders) {169 auto Style = getStyle("LLVM", "a.h", "none",170 "static const char *names[] = {[0] = \"foo\",\n"171 "[kBar] = \"bar\"};");172 ASSERT_TRUE((bool)Style);173 EXPECT_EQ(FormatStyle::LK_Cpp, Style->Language);174 175 Style = getStyle("LLVM", "a.h", "none",176 "static const char *names[] = {[0] EQ \"foo\",\n"177 "[kBar] EQ \"bar\"};");178 ASSERT_TRUE((bool)Style);179 EXPECT_EQ(FormatStyle::LK_Cpp, Style->Language);180}181 182TEST_F(FormatTestObjC, FormatObjCTryCatch) {183 verifyFormat("@try {\n"184 " f();\n"185 "} @catch (NSException e) {\n"186 " @throw;\n"187 "} @finally {\n"188 " exit(42);\n"189 "}");190 verifyFormat("DEBUG({\n"191 " @try {\n"192 " } @finally {\n"193 " }\n"194 "});");195}196 197TEST_F(FormatTestObjC, FormatObjCAutoreleasepool) {198 verifyFormat("@autoreleasepool {\n"199 " f();\n"200 "}\n"201 "@autoreleasepool {\n"202 " f();\n"203 "}");204 Style.BreakBeforeBraces = FormatStyle::BS_Custom;205 Style.BraceWrapping.AfterControlStatement = FormatStyle::BWACS_Always;206 verifyFormat("@autoreleasepool\n"207 "{\n"208 " f();\n"209 "}\n"210 "@autoreleasepool\n"211 "{\n"212 " f();\n"213 "}");214}215 216TEST_F(FormatTestObjC, FormatObjCGenerics) {217 Style.ColumnLimit = 40;218 verifyFormat("int aaaaaaaaaaaaaaaa(\n"219 " NSArray<aaaaaaaaaaaaaaaaaa *>\n"220 " aaaaaaaaaaaaaaaaa);");221 verifyFormat("int aaaaaaaaaaaaaaaa(\n"222 " NSArray<aaaaaaaaaaaaaaaaaaa<\n"223 " aaaaaaaaaaaaaaaa *> *>\n"224 " aaaaaaaaaaaaaaaaa);");225}226 227TEST_F(FormatTestObjC, FormatObjCSynchronized) {228 verifyFormat("@synchronized(self) {\n"229 " f();\n"230 "}\n"231 "@synchronized(self) {\n"232 " f();\n"233 "}");234 Style.BreakBeforeBraces = FormatStyle::BS_Custom;235 Style.BraceWrapping.AfterControlStatement = FormatStyle::BWACS_Always;236 verifyFormat("@synchronized(self)\n"237 "{\n"238 " f();\n"239 "}\n"240 "@synchronized(self)\n"241 "{\n"242 " f();\n"243 "}");244}245 246TEST_F(FormatTestObjC, FormatObjCInterface) {247 verifyFormat("@interface Foo : NSObject <NSSomeDelegate> {\n"248 "@public\n"249 " int field1;\n"250 "@protected\n"251 " int field2;\n"252 "@private\n"253 " int field3;\n"254 "@package\n"255 " int field4;\n"256 "}\n"257 "+ (id)init;\n"258 "@end");259 260 verifyFormat("@interface /* wait for it */ Foo\n"261 "+ (id)init;\n"262 "// Look, a comment!\n"263 "- (int)answerWith:(int)i;\n"264 "@end");265 266 verifyFormat("@interface Foo\n"267 "@end\n"268 "@interface Bar\n"269 "@end");270 271 verifyFormat("@interface Foo : Bar\n"272 "@property(assign, readwrite) NSInteger bar;\n"273 "+ (id)init;\n"274 "@end");275 276 verifyFormat("FOUNDATION_EXPORT NS_AVAILABLE_IOS(10.0) @interface Foo : Bar\n"277 "@property(assign, readwrite) NSInteger bar;\n"278 "+ (id)init;\n"279 "@end");280 281 verifyFormat("@interface Foo : /**/ Bar /**/ <Baz, /**/ Quux>\n"282 "+ (id)init;\n"283 "@end");284 285 verifyFormat("@interface Foo (HackStuff)\n"286 "+ (id)init;\n"287 "@end");288 289 verifyFormat("@interface Foo ()\n"290 "+ (id)init;\n"291 "@end");292 293 verifyFormat("@interface Foo (HackStuff) <MyProtocol>\n"294 "+ (id)init;\n"295 "@end");296 297 verifyFormat("@interface Foo {\n"298 " int _i;\n"299 "}\n"300 "+ (id)init;\n"301 "@end");302 303 verifyFormat("@interface Foo : Bar {\n"304 " int _i;\n"305 "}\n"306 "+ (id)init;\n"307 "@end");308 309 verifyFormat("@interface Foo : Bar <Baz, Quux> {\n"310 " int _i;\n"311 "}\n"312 "+ (id)init;\n"313 "@end");314 315 verifyFormat("@interface Foo<Baz : Blech> : Bar <Baz, Quux> {\n"316 " int _i;\n"317 "}\n"318 "+ (id)init;\n"319 "@end");320 321 verifyFormat("@interface Foo<Bar : Baz <Blech>> : Xyzzy <Corge> {\n"322 " int _i;\n"323 "}\n"324 "+ (id)init;\n"325 "@end");326 327 verifyFormat("@interface Foo<Bar : Baz <Blech>> : Xyzzy <Corge> <Quux> {\n"328 " int _i;\n"329 "}\n"330 "+ (id)init;\n"331 "@end");332 333 verifyFormat("@interface Foo : Bar <Baz> <Blech>\n"334 "@end");335 336 verifyFormat("@interface Foo : Bar <Baz> <Blech, Xyzzy, Corge>\n"337 "@end");338 339 verifyFormat("@interface Foo (HackStuff) {\n"340 " int _i;\n"341 "}\n"342 "+ (id)init;\n"343 "@end");344 345 verifyFormat("@interface Foo () {\n"346 " int _i;\n"347 "}\n"348 "+ (id)init;\n"349 "@end");350 351 verifyFormat("@interface Foo (HackStuff) <MyProtocol> {\n"352 " int _i;\n"353 "}\n"354 "+ (id)init;\n"355 "@end");356 verifyFormat("@interface Foo\n"357 "- (void)foo {\n"358 "}\n"359 "@end\n"360 "@implementation Bar\n"361 "- (void)bar {\n"362 "}\n"363 "@end");364 Style.ColumnLimit = 40;365 verifyFormat("@interface ccccccccccccc () <\n"366 " ccccccccccccc, ccccccccccccc,\n"367 " ccccccccccccc, ccccccccccccc> {\n"368 "}");369 verifyFormat("@interface ccccccccccccc (ccccccccccc) <\n"370 " ccccccccccccc> {\n"371 "}");372 Style.ObjCBinPackProtocolList = FormatStyle::BPS_Never;373 verifyFormat("@interface ddddddddddddd () <\n"374 " ddddddddddddd,\n"375 " ddddddddddddd,\n"376 " ddddddddddddd,\n"377 " ddddddddddddd> {\n"378 "}");379 380 Style.BinPackParameters = FormatStyle::BPPS_OnePerLine;381 Style.ObjCBinPackProtocolList = FormatStyle::BPS_Auto;382 verifyFormat("@interface eeeeeeeeeeeee () <\n"383 " eeeeeeeeeeeee,\n"384 " eeeeeeeeeeeee,\n"385 " eeeeeeeeeeeee,\n"386 " eeeeeeeeeeeee> {\n"387 "}");388 Style.ObjCBinPackProtocolList = FormatStyle::BPS_Always;389 verifyFormat("@interface fffffffffffff () <\n"390 " fffffffffffff, fffffffffffff,\n"391 " fffffffffffff, fffffffffffff> {\n"392 "}");393 394 Style = getGoogleStyle(FormatStyle::LK_ObjC);395 verifyFormat("@interface Foo : NSObject <NSSomeDelegate> {\n"396 " @public\n"397 " int field1;\n"398 " @protected\n"399 " int field2;\n"400 " @private\n"401 " int field3;\n"402 " @package\n"403 " int field4;\n"404 "}\n"405 "+ (id)init;\n"406 "@end");407 verifyFormat("@interface Foo : Bar <Baz, Quux>\n"408 "+ (id)init;\n"409 "@end");410 verifyFormat("@interface Foo (HackStuff) <MyProtocol>\n"411 "+ (id)init;\n"412 "@end");413 Style.ColumnLimit = 40;414 // BinPackParameters should be BPPS_BinPack by default.415 verifyFormat("void eeeeeeee(int eeeee, int eeeee,\n"416 " int eeeee, int eeeee);");417 // ObjCBinPackProtocolList should be BPS_Never by default.418 verifyFormat("@interface fffffffffffff () <\n"419 " fffffffffffff,\n"420 " fffffffffffff,\n"421 " fffffffffffff,\n"422 " fffffffffffff> {\n"423 "}");424 verifyFormat("@interface ggggggggggggg\n"425 " : ggggggggggggg <ggggggggggggg>\n"426 " <ggggggggggggg>\n"427 "@end");428}429 430TEST_F(FormatTestObjC, FormatObjCImplementation) {431 verifyFormat("@implementation Foo : NSObject {\n"432 "@public\n"433 " int field1;\n"434 "@protected\n"435 " int field2;\n"436 "@private\n"437 " int field3;\n"438 "@package\n"439 " int field4;\n"440 "}\n"441 "+ (id)init {\n}\n"442 "@end");443 444 verifyFormat("@implementation Foo\n"445 "+ (id)init {\n"446 " if (true)\n"447 " return nil;\n"448 "}\n"449 "// Look, a comment!\n"450 "- (int)answerWith:(int)i {\n"451 " return i;\n"452 "}\n"453 "+ (int)answerWith:(int)i {\n"454 " return i;\n"455 "}\n"456 "@end");457 458 verifyFormat("@implementation Foo\n"459 "@end\n"460 "@implementation Bar\n"461 "@end");462 463 EXPECT_EQ("@implementation Foo : Bar\n"464 "+ (id)init {\n}\n"465 "- (void)foo {\n}\n"466 "@end",467 format("@implementation Foo : Bar\n"468 "+(id)init{}\n"469 "-(void)foo{}\n"470 "@end"));471 472 verifyFormat("@implementation Foo {\n"473 " int _i;\n"474 "}\n"475 "+ (id)init {\n}\n"476 "@end");477 478 verifyFormat("@implementation Foo : Bar {\n"479 " int _i;\n"480 "}\n"481 "+ (id)init {\n}\n"482 "@end");483 484 verifyFormat("@implementation Foo (HackStuff)\n"485 "+ (id)init {\n}\n"486 "@end");487 verifyFormat("@implementation ObjcClass\n"488 "- (void)method;\n"489 "{}\n"490 "@end");491 492 Style = getGoogleStyle(FormatStyle::LK_ObjC);493 verifyFormat("@implementation Foo : NSObject {\n"494 " @public\n"495 " int field1;\n"496 " @protected\n"497 " int field2;\n"498 " @private\n"499 " int field3;\n"500 " @package\n"501 " int field4;\n"502 "}\n"503 "+ (id)init {\n}\n"504 "@end");505}506 507TEST_F(FormatTestObjC, FormatObjCProtocol) {508 verifyFormat("@protocol Foo\n"509 "@property(weak) id delegate;\n"510 "- (NSUInteger)numberOfThings;\n"511 "@end");512 513 verifyFormat("@protocol MyProtocol <NSObject>\n"514 "- (NSUInteger)numberOfThings;\n"515 "@end");516 517 verifyFormat("@protocol Foo;\n"518 "@protocol Bar;");519 520 verifyFormat("@protocol Foo\n"521 "@end\n"522 "@protocol Bar\n"523 "@end");524 525 verifyFormat("FOUNDATION_EXPORT NS_AVAILABLE_IOS(10.0) @protocol Foo\n"526 "@property(assign, readwrite) NSInteger bar;\n"527 "@end");528 529 verifyFormat("@protocol myProtocol\n"530 "- (void)mandatoryWithInt:(int)i;\n"531 "@optional\n"532 "- (void)optional;\n"533 "@required\n"534 "- (void)required;\n"535 "@optional\n"536 "@property(assign) int madProp;\n"537 "@end");538 539 verifyFormat("@property(nonatomic, assign, readonly)\n"540 " int *looooooooooooooooooooooooooooongNumber;\n"541 "@property(nonatomic, assign, readonly)\n"542 " NSString *looooooooooooooooooooooooooooongName;");543 544 verifyFormat("@implementation PR18406\n"545 "}\n"546 "@end");547 548 Style = getGoogleStyle(FormatStyle::LK_ObjC);549 verifyFormat("@protocol MyProtocol <NSObject>\n"550 "- (NSUInteger)numberOfThings;\n"551 "@end");552}553 554TEST_F(FormatTestObjC, FormatObjCMethodDeclarations) {555 verifyFormat("- (void)doSomethingWith:(GTMFoo *)theFoo\n"556 " rect:(NSRect)theRect\n"557 " interval:(float)theInterval {\n"558 "}");559 verifyFormat("- (void)shortf:(GTMFoo *)theFoo\n"560 " longKeyword:(NSRect)theRect\n"561 " longerKeyword:(float)theInterval\n"562 " error:(NSError **)theError {\n"563 "}");564 verifyFormat("- (void)shortf:(GTMFoo *)theFoo\n"565 " longKeyword:(NSRect)theRect\n"566 " evenLongerKeyword:(float)theInterval\n"567 " error:(NSError **)theError {\n"568 "}");569 verifyFormat("+ (instancetype)new;");570 571 verifyFormat("/*\n"572 " */\n"573 "- (void)foo;",574 "/*\n"575 " */- (void)foo;");576 577 Style.ColumnLimit = 60;578 verifyFormat("- (instancetype)initXxxxxx:(id<x>)x\n"579 " y:(id<yyyyyyyyyyyyyyyyyyyy>)y\n"580 " NS_DESIGNATED_INITIALIZER;");581 verifyFormat("- (void)drawRectOn:(id)surface\n"582 " ofSize:(size_t)height\n"583 " :(size_t)width;");584 Style.ColumnLimit = 40;585 // Make sure selectors with 0, 1, or more arguments are indented when wrapped.586 verifyFormat("- (aaaaaaaaaaaaaaaaaaaaaaaaaaaaa)\n"587 " aaaaaaaaaaaaaaaaaaaaaaaaaaaa;");588 verifyFormat("- (aaaaaaaaaaaaaaaaaaaaaaaaaaaaa)\n"589 " aaaaaaaaaaaaaaaaaaaaaaaaaaaa:(int)a;");590 verifyFormat("- (aaaaaaaaaaaaaaaaaaaaaaaaaaaaa)\n"591 " aaaaaaaaaaaaaaaaaaaaaaaaaaaa:(int)a\n"592 " aaaaaaaaaaaaaaaaaaaaaaaaaaaa:(int)a;");593 verifyFormat("- (aaaaaaaaaaaaaaaaaaaaaaaaaaaaa)\n"594 " aaaaaaaaaaaaaaaaaaaaaaaaaaa:(int)a\n"595 " aaaaaaaaaaaaaaaaaaaaaaaaaaaa:(int)a;");596 verifyFormat("- (aaaaaaaaaaaaaaaaaaaaaaaaaaaaa)\n"597 " aaaaaaaaaaaaaaaaaaaaaaaaaaaa:(int)a\n"598 " aaaaaaaaaaaaaaaaaaaaaaaaaaa:(int)a;");599 600 // Continuation indent width should win over aligning colons if the function601 // name is long.602 Style = getGoogleStyle(FormatStyle::LK_ObjC);603 Style.ColumnLimit = 40;604 verifyFormat("- (void)shortf:(GTMFoo *)theFoo\n"605 " dontAlignNamef:(NSRect)theRect {\n"606 "}");607 608 // Make sure we don't break aligning for short parameter names.609 verifyFormat("- (void)shortf:(GTMFoo *)theFoo\n"610 " aShortf:(NSRect)theRect {\n"611 "}");612 613 // Format pairs correctly.614 Style.ColumnLimit = 80;615 verifyFormat("- (void)drawRectOn:(id)surface\n"616 " ofSize:(aaaaaaaa)height\n"617 " :(size_t)width\n"618 " atOrigin:(size_t)x\n"619 " :(size_t)y\n"620 " aaaaa:(a)yyy\n"621 " bbb:(d)cccc;");622 verifyFormat("- (void)drawRectOn:(id)surface ofSize:(aaa)height:(bbb)width;");623 624 // BraceWrapping AfterFunction is respected for ObjC methods625 Style = getGoogleStyle(FormatStyle::LK_ObjC);626 Style.BreakBeforeBraces = FormatStyle::BS_Custom;627 Style.BraceWrapping.AfterFunction = true;628 verifyFormat("@implementation Foo\n"629 "- (void)foo:(id)bar\n"630 "{\n"631 "}\n"632 "@end");633}634 635TEST_F(FormatTestObjC, FormatObjCMethodExpr) {636 verifyFormat("[foo bar:baz];");637 verifyFormat("[foo bar]->baz;");638 verifyFormat("return [foo bar:baz];");639 verifyFormat("return (a)[foo bar:baz];");640 verifyFormat("f([foo bar:baz]);");641 verifyFormat("f(2, [foo bar:baz]);");642 verifyFormat("f(2, a ? b : c);");643 verifyFormat("[[self initWithInt:4] bar:[baz quux:arrrr]];");644 645 // Unary operators.646 verifyFormat("int a = +[foo bar:baz];");647 verifyFormat("int a = -[foo bar:baz];");648 verifyFormat("int a = ![foo bar:baz];");649 verifyFormat("int a = ~[foo bar:baz];");650 verifyFormat("int a = ++[foo bar:baz];");651 verifyFormat("int a = --[foo bar:baz];");652 verifyFormat("int a = sizeof [foo bar:baz];");653 verifyFormat("int a = alignof [foo bar:baz];");654 verifyFormat("int a = &[foo bar:baz];");655 verifyFormat("int a = *[foo bar:baz];");656 // FIXME: Make casts work, without breaking f()[4].657 // verifyFormat("int a = (int)[foo bar:baz];");658 // verifyFormat("return (int)[foo bar:baz];");659 // verifyFormat("(void)[foo bar:baz];");660 verifyFormat("return (MyType *)[self.tableView cellForRowAtIndexPath:cell];");661 662 // Binary operators.663 verifyFormat("[foo bar:baz], [foo bar:baz];");664 verifyFormat("[foo bar:baz] = [foo bar:baz];");665 verifyFormat("[foo bar:baz] *= [foo bar:baz];");666 verifyFormat("[foo bar:baz] /= [foo bar:baz];");667 verifyFormat("[foo bar:baz] %= [foo bar:baz];");668 verifyFormat("[foo bar:baz] += [foo bar:baz];");669 verifyFormat("[foo bar:baz] -= [foo bar:baz];");670 verifyFormat("[foo bar:baz] <<= [foo bar:baz];");671 verifyFormat("[foo bar:baz] >>= [foo bar:baz];");672 verifyFormat("[foo bar:baz] &= [foo bar:baz];");673 verifyFormat("[foo bar:baz] ^= [foo bar:baz];");674 verifyFormat("[foo bar:baz] |= [foo bar:baz];");675 verifyFormat("[foo bar:baz] ? [foo bar:baz] : [foo bar:baz];");676 verifyFormat("[foo bar:baz] || [foo bar:baz];");677 verifyFormat("[foo bar:baz] && [foo bar:baz];");678 verifyFormat("[foo bar:baz] | [foo bar:baz];");679 verifyFormat("[foo bar:baz] ^ [foo bar:baz];");680 verifyFormat("[foo bar:baz] & [foo bar:baz];");681 verifyFormat("[foo bar:baz] == [foo bar:baz];");682 verifyFormat("[foo bar:baz] != [foo bar:baz];");683 verifyFormat("[foo bar:baz] >= [foo bar:baz];");684 verifyFormat("[foo bar:baz] <= [foo bar:baz];");685 verifyFormat("[foo bar:baz] > [foo bar:baz];");686 verifyFormat("[foo bar:baz] < [foo bar:baz];");687 verifyFormat("[foo bar:baz] >> [foo bar:baz];");688 verifyFormat("[foo bar:baz] << [foo bar:baz];");689 verifyFormat("[foo bar:baz] - [foo bar:baz];");690 verifyFormat("[foo bar:baz] + [foo bar:baz];");691 verifyFormat("[foo bar:baz] * [foo bar:baz];");692 verifyFormat("[foo bar:baz] / [foo bar:baz];");693 verifyFormat("[foo bar:baz] % [foo bar:baz];");694 // Whew!695 696 verifyFormat("return in[42];");697 verifyFormat("for (auto v : in[1]) {\n}");698 verifyFormat("for (int i = 0; i < in[a]; ++i) {\n}");699 verifyFormat("for (int i = 0; in[a] < i; ++i) {\n}");700 verifyFormat("for (int i = 0; i < n; ++i, ++in[a]) {\n}");701 verifyFormat("for (int i = 0; i < n; ++i, in[a]++) {\n}");702 verifyFormat("for (int i = 0; i < f(in[a]); ++i, in[a]++) {\n}");703 verifyFormat("for (id foo in [self getStuffFor:bla]) {\n"704 "}");705 verifyFormat("[self aaaaa:MACRO(a, b:, c:)];");706 verifyFormat("[self aaaaa:MACRO(a, b:c:, d:e:)];");707 verifyFormat("[self aaaaa:MACRO(a, b:c:d:, e:f:g:)];");708 verifyFormat("int XYMyFoo(int a, int b) NS_SWIFT_NAME(foo(self:scale:));");709 verifyFormat("[self aaaaa:(1 + 2) bbbbb:3];");710 verifyFormat("[self aaaaa:(Type)a bbbbb:3];");711 712 verifyFormat("[self stuffWithInt:(4 + 2) float:4.5];");713 verifyFormat("[self stuffWithInt:a ? b : c float:4.5];");714 verifyFormat("[self stuffWithInt:a ? [self foo:bar] : c];");715 verifyFormat("[self stuffWithInt:a ? (e ? f : g) : c];");716 verifyFormat("[cond ? obj1 : obj2 methodWithParam:param]");717 verifyFormat("[button setAction:@selector(zoomOut:)];");718 verifyFormat("[color getRed:&r green:&g blue:&b alpha:&a];");719 720 verifyFormat("arr[[self indexForFoo:a]];");721 verifyFormat("throw [self errorFor:a];");722 verifyFormat("@throw [self errorFor:a];");723 724 verifyFormat("[(id)foo bar:(id)baz quux:(id)snorf];");725 verifyFormat("[(id)foo bar:(id) ? baz : quux];");726 verifyFormat("4 > 4 ? (id)a : (id)baz;");727 728 unsigned PreviousColumnLimit = Style.ColumnLimit;729 Style.ColumnLimit = 50;730 // Instead of:731 // bool a =732 // ([object a:42] == 0 || [object a:42733 // b:42] == 0);734 verifyFormat("bool a = ([object a:42] == 0 ||\n"735 " [object a:42 b:42] == 0);");736 Style.ColumnLimit = PreviousColumnLimit;737 verifyFormat("bool a = ([aaaaaaaa aaaaa] == aaaaaaaaaaaaaaaaa ||\n"738 " [aaaaaaaa aaaaa] == aaaaaaaaaaaaaaaaaaaa);");739 740 // This tests that the formatter doesn't break after "backing" but before ":",741 // which would be at 80 columns.742 verifyFormat(743 "void f() {\n"744 " if ((self = [super initWithContentRect:contentRect\n"745 " styleMask:styleMask ?: otherMask\n"746 " backing:NSBackingStoreBuffered\n"747 " defer:YES]))");748 749 verifyFormat(750 "[foo checkThatBreakingAfterColonWorksOk:\n"751 " [bar ifItDoes:reduceOverallLineLengthLikeInThisCase]];");752 753 verifyFormat("[myObj short:arg1 // Force line break\n"754 " longKeyword:arg2 != nil ? arg2 : @\"longKeyword\"\n"755 " evenLongerKeyword:arg3 ?: @\"evenLongerKeyword\"\n"756 " error:arg4];");757 verifyFormat(758 "void f() {\n"759 " popup_window_.reset([[RenderWidgetPopupWindow alloc]\n"760 " initWithContentRect:NSMakeRect(origin_global.x, origin_global.y,\n"761 " pos.width(), pos.height())\n"762 " styleMask:NSBorderlessWindowMask\n"763 " backing:NSBackingStoreBuffered\n"764 " defer:NO]);\n"765 "}");766 Style.ColumnLimit = 63;767 verifyFormat(768 "- (void)test {\n"769 " if ([object\n"770 " respondsToSelector:@selector(\n"771 " selectorName:param1:param2:)])\n"772 " return;\n"773 "}");774 Style.ColumnLimit = PreviousColumnLimit;775 verifyFormat("[contentsContainer replaceSubview:[subviews objectAtIndex:0]\n"776 " with:contentsNativeView];");777 778 verifyFormat(779 "[pboard addTypes:[NSArray arrayWithObject:kBookmarkButtonDragType]\n"780 " owner:nillllll];");781 782 verifyFormat(783 "[pboard setData:[NSData dataWithBytes:&button length:sizeof(button)]\n"784 " forType:kBookmarkButtonDragType];");785 786 verifyFormat("[defaultCenter addObserver:self\n"787 " selector:@selector(willEnterFullscreen)\n"788 " name:kWillEnterFullscreenNotification\n"789 " object:nil];");790 verifyFormat("[image_rep drawInRect:drawRect\n"791 " fromRect:NSZeroRect\n"792 " operation:NSCompositeCopy\n"793 " fraction:1.0\n"794 " respectFlipped:NO\n"795 " hints:nil];");796 verifyFormat("[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"797 " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa];");798 verifyFormat("[aaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaa)\n"799 " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa];");800 verifyFormat("[aaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaa[aaaaaaaaaaaaaaaaaaaaa]\n"801 " aaaaaaaaaaaaaaaaaaaaaa];");802 803 verifyFormat(804 "scoped_nsobject<NSTextField> message(\n"805 " // The frame will be fixed up when |-setMessageText:| is called.\n"806 " [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 0, 0)]);");807 verifyFormat("[self aaaaaa:bbbbbbbbbbbbb\n"808 " aaaaaaaaaa:bbbbbbbbbbbbbbbbb\n"809 " aaaaa:bbbbbbbbbbb + bbbbbbbbbbbb\n"810 " aaaa:bbb];");811 verifyFormat("[self param:function( //\n"812 " parameter)]");813 verifyFormat(814 "[self aaaaaaaaaa:aaaaaaaaaaaaaaa | aaaaaaaaaaaaaaa | aaaaaaaaaaaaaaa |\n"815 " aaaaaaaaaaaaaaa | aaaaaaaaaaaaaaa | aaaaaaaaaaaaaaa |\n"816 " aaaaaaaaaaaaaaa | aaaaaaaaaaaaaaa];");817 818 // Variadic parameters.819 verifyFormat(820 "NSArray *myStrings = [NSArray stringarray:@\"a\", @\"b\", nil];");821 verifyFormat(822 "[self aaaaaaaaaaaaa:aaaaaaaaaaaaaaa, aaaaaaaaaaaaaaa, aaaaaaaaaaaaaaa,\n"823 " aaaaaaaaaaaaaaa, aaaaaaaaaaaaaaa, aaaaaaaaaaaaaaa,\n"824 " aaaaaaaaaaaaaaa, aaaaaaaaaaaaaaa];");825 826 verifyFormat("[self // break\n"827 " a:a\n"828 " aaa:aaa];");829 830 // Formats pair-parameters.831 verifyFormat("[I drawRectOn:surface ofSize:aa:bbb atOrigin:cc:dd];");832 verifyFormat("[I drawRectOn:surface //\n"833 " ofSize:aa:bbb\n"834 " atOrigin:cc:dd];");835 836 // Inline block as a first argument.837 verifyFormat("[object justBlock:^{\n"838 " a = 42;\n"839 "}];");840 verifyFormat("[object\n"841 " justBlock:^{\n"842 " a = 42;\n"843 " }\n"844 " notBlock:42\n"845 " a:42];");846 verifyFormat("[object\n"847 " firstBlock:^{\n"848 " a = 42;\n"849 " }\n"850 " blockWithLongerName:^{\n"851 " a = 42;\n"852 " }];");853 verifyFormat("[object\n"854 " blockWithLongerName:^{\n"855 " a = 42;\n"856 " }\n"857 " secondBlock:^{\n"858 " a = 42;\n"859 " }];");860 verifyFormat("[object\n"861 " firstBlock:^{\n"862 " a = 42;\n"863 " }\n"864 " notBlock:42\n"865 " secondBlock:^{\n"866 " a = 42;\n"867 " }];");868 869 // Space between cast rparen and selector name component.870 verifyFormat("[((Foo *)foo) bar];");871 verifyFormat("[((Foo *)foo) bar:1 blech:2];");872 873 Style.ColumnLimit = 20;874 verifyFormat("aaaaa = [a aa:aa\n"875 " aa:aa];");876 verifyFormat("aaaaaa = [aa aa:aa\n"877 " aa:aa];");878 879 // Message receiver taking multiple lines.880 // Non-corner case.881 verifyFormat("[[object block:^{\n"882 " return 42;\n"883 "}] a:42 b:42];");884 // Arguments just fit into one line.885 verifyFormat("[[object block:^{\n"886 " return 42;\n"887 "}] aaaaaaa:42 b:42];");888 // Arguments just over a column limit.889 verifyFormat("[[object block:^{\n"890 " return 42;\n"891 "}] aaaaaaa:42\n"892 " bb:42];");893 // Arguments just fit into one line.894 Style.ColumnLimit = 23;895 verifyFormat("[[obj a:42\n"896 " b:42\n"897 " c:42\n"898 " d:42] e:42 f:42];");899 900 // Arguments do not fit into one line with a receiver.901 Style.ColumnLimit = 20;902 verifyFormat("[[obj a:42] a:42\n"903 " b:42];");904 verifyFormat("[[obj a:42] a:42\n"905 " b:42\n"906 " c:42];");907 verifyFormat("[[obj aaaaaa:42\n"908 " b:42]\n"909 " cc:42\n"910 " d:42];");911 912 // Avoid breaking receiver expression.913 Style.ColumnLimit = 30;914 verifyFormat("fooooooo =\n"915 " [[obj fooo] aaa:42\n"916 " aaa:42];");917 verifyFormat("[[[obj foo] bar] aa:42\n"918 " bb:42\n"919 " cc:42];");920 921 // Avoid breaking between unary operators and ObjC method expressions.922 Style.ColumnLimit = 45;923 verifyFormat("if (a012345678901234567890123 &&\n"924 " ![foo bar]) {\n"925 "}");926 verifyFormat("if (a012345678901234567890123 &&\n"927 " +[foo bar]) {\n"928 "}");929 verifyFormat("if (a012345678901234567890123 &&\n"930 " -[foo bar]) {\n"931 "}");932 933 Style.ColumnLimit = 70;934 verifyFormat(935 "void f() {\n"936 " popup_wdow_.reset([[RenderWidgetPopupWindow alloc]\n"937 " iniithContentRect:NSMakRet(origin_global.x, origin_global.y,\n"938 " pos.width(), pos.height())\n"939 " syeMask:NSBorderlessWindowMask\n"940 " bking:NSBackingStoreBuffered\n"941 " der:NO]);\n"942 "}");943 944 Style.ColumnLimit = 60;945 verifyFormat("[call aaaaaaaa.aaaaaa.aaaaaaaa.aaaaaaaa.aaaaaaaa.aaaaaaaa\n"946 " .aaaaaaaa];"); // FIXME: Indentation seems off.947 // FIXME: This violates the column limit.948 verifyFormat(949 "[aaaaaaaaaaaaaaaaaaaaaaaaa\n"950 " aaaaaaaaaaaaaaaaa:aaaaaaaa\n"951 " aaa:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa];");952 verifyFormat("[objectName\n"953 " respondsToSelector:\n"954 " @selector(\n"955 " somelonglonglonglongnameeeeeeee:\n"956 " loooooooooanotherlonglonglonglongnametopush:\n"957 " otherlongnameforlimit:)];");958 959 Style = getChromiumStyle(FormatStyle::LK_ObjC);960 Style.ColumnLimit = 80;961 verifyFormat(962 "void f() {\n"963 " popup_window_.reset([[RenderWidgetPopupWindow alloc]\n"964 " initWithContentRect:NSMakeRect(origin_global.x, origin_global.y,\n"965 " pos.width(), pos.height())\n"966 " styleMask:NSBorderlessWindowMask\n"967 " backing:NSBackingStoreBuffered\n"968 " defer:NO]);\n"969 "}");970 971 // Respect continuation indent and colon alignment (e.g. when object name is972 // short, and first selector is the longest one)973 Style = getLLVMStyle();974 Style.Language = FormatStyle::LK_ObjC;975 Style.ContinuationIndentWidth = 8;976 verifyFormat("[self performSelectorOnMainThread:@selector(loadAccessories)\n"977 " withObject:nil\n"978 " waitUntilDone:false];");979 verifyFormat("[self performSelector:@selector(loadAccessories)\n"980 " withObjectOnMainThread:nil\n"981 " waitUntilDone:false];");982 verifyFormat(983 "[aaaaaaaaaaaaaaaaaaaaaaaaa\n"984 " performSelectorOnMainThread:@selector(loadAccessories)\n"985 " withObject:nil\n"986 " waitUntilDone:false];");987 verifyFormat(988 "[self // force wrapping\n"989 " performSelectorOnMainThread:@selector(loadAccessories)\n"990 " withObject:nil\n"991 " waitUntilDone:false];");992 993 // The appropriate indentation is used after a block statement.994 Style.ContinuationIndentWidth = 4;995 verifyFormat(996 "void aaaaaaaaaaaaaaaaaaaaa(int c) {\n"997 " if (c) {\n"998 " f();\n"999 " }\n"1000 " [dddddddddddddddddddddddddddddddddddddddddddddddddddddddd\n"1001 " eeeeeeeeeeeeeeeeeeeeeeeeeeeee:^(fffffffffffffff gggggggg) {\n"1002 " f(SSSSS, c);\n"1003 " }];\n"1004 "}");1005}1006 1007TEST_F(FormatTestObjC, ObjCAt) {1008 verifyFormat("@autoreleasepool");1009 verifyFormat("@catch");1010 verifyFormat("@class");1011 verifyFormat("@compatibility_alias");1012 verifyFormat("@defs");1013 verifyFormat("@dynamic");1014 verifyFormat("@encode");1015 verifyFormat("@end");1016 verifyFormat("@finally");1017 verifyFormat("@implementation");1018 verifyFormat("@import");1019 verifyFormat("@interface");1020 verifyFormat("@optional");1021 verifyFormat("@package");1022 verifyFormat("@private");1023 verifyFormat("@property");1024 verifyFormat("@protected");1025 verifyFormat("@protocol");1026 verifyFormat("@public");1027 verifyFormat("@required");1028 verifyFormat("@selector");1029 verifyFormat("@synchronized");1030 verifyFormat("@synthesize");1031 verifyFormat("@throw");1032 verifyFormat("@try");1033 1034 EXPECT_EQ("@interface", format("@ interface"));1035 1036 // The precise formatting of this doesn't matter, nobody writes code like1037 // this.1038 verifyFormat("@ /*foo*/ interface");1039}1040 1041TEST_F(FormatTestObjC, ObjCBlockTypesAndVariables) {1042 verifyFormat("void DoStuffWithBlockType(int (^)(char));");1043 verifyFormat("int (^foo)(char, float);");1044 verifyFormat("int (^foo[10])(char, float);");1045 verifyFormat("int (^foo[kNumEntries])(char, float);");1046 verifyFormat("int (^foo[kNumEntries + 10])(char, float);");1047 verifyFormat("int (^foo[(kNumEntries + 10)])(char, float);");1048 1049 verifyFormat("int *p = ^int *() { //\n"1050 " return nullptr;\n"1051 "}();");1052 1053 verifyFormat("int * (^p)(void) = ^int *(void) { //\n"1054 " return nullptr;\n"1055 "};");1056 1057 // WebKit forces function braces onto a newline, but blocks should not.1058 verifyFormat("int* p = ^int*() { //\n"1059 " return nullptr;\n"1060 "}();",1061 getWebKitStyle());1062}1063 1064TEST_F(FormatTestObjC, ObjCSnippets) {1065 verifyFormat("@autoreleasepool {\n"1066 " foo();\n"1067 "}");1068 verifyFormat("@class Foo, Bar;");1069 verifyFormat("@compatibility_alias AliasName ExistingClass;");1070 verifyFormat("@dynamic textColor;");1071 verifyFormat("char *buf1 = @encode(int *);");1072 verifyFormat("char *buf1 = @encode(typeof(4 * 5));");1073 verifyFormat("char *buf1 = @encode(int **);");1074 verifyFormat("Protocol *proto = @protocol(p1);");1075 verifyFormat("SEL s = @selector(foo:);");1076 verifyFormat("@synchronized(self) {\n"1077 " f();\n"1078 "}");1079 1080 verifyFormat("@import foo.bar;\n"1081 "@import baz;");1082 1083 verifyFormat("@synthesize dropArrowPosition = dropArrowPosition_;");1084 1085 verifyFormat("@property(assign, nonatomic) CGFloat hoverAlpha;");1086 verifyFormat("@property(assign, getter=isEditable) BOOL editable;");1087 1088 verifyFormat("extern UIWindow *MainWindow(void) "1089 "NS_SWIFT_NAME(getter:MyHelper.mainWindow());");1090 1091 verifyFormat("extern UIWindow *MainWindow(void) "1092 "CF_SWIFT_NAME(getter:MyHelper.mainWindow());");1093 1094 Style.ColumnLimit = 50;1095 verifyFormat("@interface Foo\n"1096 "- (void)doStuffWithFoo:(id)name\n"1097 " bar:(id)bar\n"1098 " baz:(id)baz\n"1099 " NS_SWIFT_NAME(doStuff(withFoo:bar:baz:));\n"1100 "@end");1101 1102 Style = getMozillaStyle();1103 verifyFormat("@property (assign, getter=isEditable) BOOL editable;");1104 verifyFormat("@property BOOL editable;");1105 1106 Style = getWebKitStyle();1107 verifyFormat("@property (assign, getter=isEditable) BOOL editable;");1108 verifyFormat("@property BOOL editable;");1109 1110 Style = getGoogleStyle(FormatStyle::LK_ObjC);1111 verifyFormat("@synthesize dropArrowPosition = dropArrowPosition_;");1112 verifyFormat("@property(assign, getter=isEditable) BOOL editable;");1113}1114 1115TEST_F(FormatTestObjC, ObjCForIn) {1116 verifyFormat("- (void)test {\n"1117 " for (NSString *n in arrayOfStrings) {\n"1118 " foo(n);\n"1119 " }\n"1120 "}");1121 verifyFormat("- (void)test {\n"1122 " for (NSString *n in (__bridge NSArray *)arrayOfStrings) {\n"1123 " foo(n);\n"1124 " }\n"1125 "}");1126 verifyFormat("for (Foo *x in bar) {\n}");1127 verifyFormat("for (Foo *x in [bar baz]) {\n}");1128 verifyFormat("for (Foo *x in [bar baz:blech]) {\n}");1129 verifyFormat("for (Foo *x in [bar baz:blech, 1, 2, 3, 0]) {\n}");1130 verifyFormat("for (Foo *x in [bar baz:^{\n"1131 " [uh oh];\n"1132 " }]) {\n}");1133}1134 1135TEST_F(FormatTestObjC, ObjCCxxKeywords) {1136 verifyFormat("+ (instancetype)new {\n"1137 " return nil;\n"1138 "}");1139 verifyFormat("+ (instancetype)myNew {\n"1140 " return [self new];\n"1141 "}");1142 verifyFormat("SEL NewSelector(void) { return @selector(new); }");1143 verifyFormat("SEL MacroSelector(void) { return MACRO(new); }");1144 verifyFormat("+ (instancetype)delete {\n"1145 " return nil;\n"1146 "}");1147 verifyFormat("+ (instancetype)myDelete {\n"1148 " return [self delete];\n"1149 "}");1150 verifyFormat("SEL DeleteSelector(void) { return @selector(delete); }");1151 verifyFormat("SEL MacroSelector(void) { return MACRO(delete); }");1152 verifyFormat("MACRO(new:)");1153 verifyFormat("MACRO(delete:)");1154 verifyFormat("foo = @{MACRO(new:) : MACRO(delete:)}");1155 verifyFormat("@implementation Foo\n"1156 "// Testing\n"1157 "- (Class)class {\n"1158 "}\n"1159 "- (void)foo {\n"1160 "}\n"1161 "@end");1162 verifyFormat("@implementation Foo\n"1163 "- (Class)class {\n"1164 "}\n"1165 "- (void)foo {\n"1166 "}\n"1167 "@end");1168 verifyFormat("@implementation Foo\n"1169 "+ (Class)class {\n"1170 "}\n"1171 "- (void)foo {\n"1172 "}\n"1173 "@end");1174 verifyFormat("@implementation Foo\n"1175 "- (Class)class:(Class)klass {\n"1176 "}\n"1177 "- (void)foo {\n"1178 "}\n"1179 "@end");1180 verifyFormat("@implementation Foo\n"1181 "+ (Class)class:(Class)klass {\n"1182 "}\n"1183 "- (void)foo {\n"1184 "}\n"1185 "@end");1186 1187 verifyFormat("@interface Foo\n"1188 "// Testing\n"1189 "- (Class)class;\n"1190 "- (void)foo;\n"1191 "@end");1192 verifyFormat("@interface Foo\n"1193 "- (Class)class;\n"1194 "- (void)foo;\n"1195 "@end");1196 verifyFormat("@interface Foo\n"1197 "+ (Class)class;\n"1198 "- (void)foo;\n"1199 "@end");1200 verifyFormat("@interface Foo\n"1201 "- (Class)class:(Class)klass;\n"1202 "- (void)foo;\n"1203 "@end");1204 verifyFormat("@interface Foo\n"1205 "+ (Class)class:(Class)klass;\n"1206 "- (void)foo;\n"1207 "@end");1208}1209 1210TEST_F(FormatTestObjC, ObjCLiterals) {1211 verifyFormat("@\"String\"");1212 verifyFormat("@1");1213 verifyFormat("@+4.8");1214 verifyFormat("@-4");1215 verifyFormat("@1LL");1216 verifyFormat("@.5");1217 verifyFormat("@'c'");1218 verifyFormat("@true");1219 1220 verifyFormat("NSNumber *smallestInt = @(-INT_MAX - 1);");1221 verifyFormat("NSNumber *piOverTwo = @(M_PI / 2);");1222 verifyFormat("NSNumber *favoriteColor = @(Green);");1223 verifyFormat("NSString *path = @(getenv(\"PATH\"));");1224 1225 verifyFormat("[dictionary setObject:@(1) forKey:@\"number\"];");1226}1227 1228TEST_F(FormatTestObjC, ObjCDictLiterals) {1229 verifyFormat("@{");1230 verifyFormat("@{}");1231 verifyFormat("@{@\"one\" : @1}");1232 verifyFormat("return @{@\"one\" : @1;");1233 verifyFormat("@{@\"one\" : @1}");1234 1235 verifyFormat("@{@\"one\" : @{@2 : @1}}");1236 verifyFormat("@{\n"1237 " @\"one\" : @{@2 : @1},\n"1238 "}");1239 1240 verifyFormat("@{1 > 2 ? @\"one\" : @\"two\" : 1 > 2 ? @1 : @2}");1241 verifyIncompleteFormat("[self setDict:@{}");1242 verifyIncompleteFormat("[self setDict:@{@1 : @2}");1243 verifyFormat("NSLog(@\"%@\", @{@1 : @2, @2 : @3}[@1]);");1244 verifyFormat(1245 "NSDictionary *masses = @{@\"H\" : @1.0078, @\"He\" : @4.0026};");1246 verifyFormat(1247 "NSDictionary *settings = @{AVEncoderKey : @(AVAudioQualityMax)};");1248 1249 verifyFormat("NSDictionary *d = @{\n"1250 " @\"nam\" : NSUserNam(),\n"1251 " @\"dte\" : [NSDate date],\n"1252 " @\"processInfo\" : [NSProcessInfo processInfo]\n"1253 "};");1254 verifyFormat(1255 "@{\n"1256 " NSFontAttributeNameeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee : "1257 "regularFont,\n"1258 "};");1259 verifyFormat(1260 "@{\n"1261 " NSFontAttributeNameeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee :\n"1262 " reeeeeeeeeeeeeeeeeeeeeeeegularFont,\n"1263 "};");1264 1265 // We should try to be robust in case someone forgets the "@".1266 verifyFormat("NSDictionary *d = {\n"1267 " @\"nam\" : NSUserNam(),\n"1268 " @\"dte\" : [NSDate date],\n"1269 " @\"processInfo\" : [NSProcessInfo processInfo]\n"1270 "};");1271 verifyFormat("NSMutableDictionary *dictionary =\n"1272 " [NSMutableDictionary dictionaryWithDictionary:@{\n"1273 " aaaaaaaaaaaaaaaaaaaaa : aaaaaaaaaaaaa,\n"1274 " bbbbbbbbbbbbbbbbbb : bbbbb,\n"1275 " cccccccccccccccc : ccccccccccccccc\n"1276 " }];");1277 1278 // Ensure that casts before the key are kept on the same line as the key.1279 verifyFormat(1280 "NSDictionary *d = @{\n"1281 " (aaaaaaaa id)aaaaaaaaa : (aaaaaaaa id)aaaaaaaaaaaaaaaaaaaaaaaa,\n"1282 " (aaaaaaaa id)aaaaaaaaaaaaaa : (aaaaaaaa id)aaaaaaaaaaaaaa,\n"1283 "};");1284 Style.ColumnLimit = 40;1285 verifyFormat("int Foo() {\n"1286 " a12345 = @{a12345 : a12345};\n"1287 "}");1288 verifyFormat("int Foo() {\n"1289 " a12345 = @{a12345 : @(a12345)};\n"1290 "}");1291 verifyFormat("int Foo() {\n"1292 " a12345 = @{(Foo *)a12345 : @(a12345)};\n"1293 "}");1294 verifyFormat("int Foo() {\n"1295 " a12345 = @{@(a12345) : a12345};\n"1296 "}");1297 verifyFormat("int Foo() {\n"1298 " a12345 = @{@(a12345) : @YES};\n"1299 "}");1300 Style.SpacesInContainerLiterals = false;1301 verifyFormat("int Foo() {\n"1302 " b12345 = @{b12345: b12345};\n"1303 "}");1304 verifyFormat("int Foo() {\n"1305 " b12345 = @{(Foo *)b12345: @(b12345)};\n"1306 "}");1307 Style.SpacesInContainerLiterals = true;1308 1309 Style = getGoogleStyle(FormatStyle::LK_ObjC);1310 verifyFormat(1311 "@{\n"1312 " NSFontAttributeNameeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee : "1313 "regularFont,\n"1314 "};");1315}1316 1317TEST_F(FormatTestObjC, ObjCArrayLiterals) {1318 verifyIncompleteFormat("@[");1319 verifyFormat("@[]");1320 verifyFormat(1321 "NSArray *array = @[ @\" Hey \", NSApp, [NSNumber numberWithInt:42] ];");1322 verifyFormat("return @[ @3, @[], @[ @4, @5 ] ];");1323 verifyFormat("NSArray *array = @[ [foo description] ];");1324 1325 verifyFormat(1326 "NSArray *some_variable = @[\n"1327 " aaaa == bbbbbbbbbbb ? @\"aaaaaaaaaaaa\" : @\"aaaaaaaaaaaaaa\",\n"1328 " @\"aaaaaaaaaaaaaaaaa\",\n"1329 " @\"aaaaaaaaaaaaaaaaa\",\n"1330 " @\"aaaaaaaaaaaaaaaaa\",\n"1331 "];");1332 verifyFormat(1333 "NSArray *some_variable = @[\n"1334 " aaaa == bbbbbbbbbbb ? @\"aaaaaaaaaaaa\" : @\"aaaaaaaaaaaaaa\",\n"1335 " @\"aaaaaaaaaaaaaaaa\", @\"aaaaaaaaaaaaaaaa\", @\"aaaaaaaaaaaaaaaa\"\n"1336 "];");1337 verifyFormat("NSArray *some_variable = @[\n"1338 " @\"aaaaaaaaaaaaaaaaa\",\n"1339 " @\"aaaaaaaaaaaaaaaaa\",\n"1340 " @\"aaaaaaaaaaaaaaaaa\",\n"1341 " @\"aaaaaaaaaaaaaaaaa\",\n"1342 "];");1343 verifyFormat("NSArray *array = @[\n"1344 " @\"a\",\n"1345 " @\"a\",\n" // Trailing comma -> one per line.1346 "];");1347 1348 // We should try to be robust in case someone forgets the "@".1349 verifyFormat("NSArray *some_variable = [\n"1350 " @\"aaaaaaaaaaaaaaaaa\",\n"1351 " @\"aaaaaaaaaaaaaaaaa\",\n"1352 " @\"aaaaaaaaaaaaaaaaa\",\n"1353 " @\"aaaaaaaaaaaaaaaaa\",\n"1354 "];");1355 verifyFormat(1356 "- (NSAttributedString *)attributedStringForSegment:(NSUInteger)segment\n"1357 " index:(NSUInteger)index\n"1358 " nonDigitAttributes:\n"1359 " (NSDictionary *)noDigitAttributes;");1360 verifyFormat("[someFunction someLooooooooooooongParameter:@[\n"1361 " NSBundle.mainBundle.infoDictionary[@\"a\"]\n"1362 "]];");1363 Style.ColumnLimit = 40;1364 verifyFormat("int Foo() {\n"1365 " a12345 = @[ a12345, a12345 ];\n"1366 "}");1367 verifyFormat("int Foo() {\n"1368 " a123 = @[ (Foo *)a12345, @(a12345) ];\n"1369 "}");1370 Style.SpacesInContainerLiterals = false;1371 verifyFormat("int Foo() {\n"1372 " b12345 = @[b12345, b12345];\n"1373 "}");1374 verifyFormat("int Foo() {\n"1375 " b12345 = @[(Foo *)b12345, @(b12345)];\n"1376 "}");1377 Style.SpacesInContainerLiterals = true;1378 Style.ColumnLimit = 20;1379 // We can't break string literals inside NSArray literals1380 // (that raises -Wobjc-string-concatenation).1381 verifyFormat("NSArray *foo = @[\n"1382 " @\"aaaaaaaaaaaaaaaaaaaaaaaaaa\"\n"1383 "];");1384}1385 1386TEST_F(FormatTestObjC, BreaksCallStatementWhereSemiJustOverTheLimit) {1387 Style.ColumnLimit = 60;1388 // If the statement starting with 'a = ...' is put on a single line, the ';'1389 // is at line 61.1390 verifyFormat("int f(int a) {\n"1391 " a = [self aaaaaaaaaa:bbbbbbbbb\n"1392 " ccccccccc:dddddddd\n"1393 " ee:fddd];\n"1394 "}");1395}1396 1397TEST_F(FormatTestObjC, AlwaysBreakBeforeMultilineStrings) {1398 Style = getGoogleStyle(FormatStyle::LK_ObjC);1399 Style.ColumnLimit = 40;1400 verifyFormat("aaaa = @\"bbbb\"\n"1401 " @\"cccc\";");1402 verifyFormat("aaaa(@\"bbbb\"\n"1403 " @\"cccc\");");1404 verifyFormat("aaaa(qqq, @\"bbbb\"\n"1405 " @\"cccc\");");1406 verifyFormat("[aaaa qqqq:@\"bbbb\"\n"1407 " @\"cccc\"];");1408 verifyFormat("aaaa = [aaaa qqqq:@\"bbbb\"\n"1409 " @\"cccc\"];");1410 verifyFormat("[aaaa qqqq:@\"bbbb\"\n"1411 " @\"cccc\"\n"1412 " rr:42\n"1413 " ssssss:@\"ee\"\n"1414 " @\"fffff\"];");1415}1416 1417TEST_F(FormatTestObjC, DisambiguatesCallsFromCppLambdas) {1418 verifyFormat("x = ([a foo:bar] && b->c == 'd');");1419 verifyFormat("x = ([a foo:bar] + b->c == 'd');");1420 verifyFormat("x = ([a foo:bar] + !b->c == 'd');");1421 verifyFormat("x = ([a foo:bar] + ~b->c == 'd');");1422 verifyFormat("x = ([a foo:bar] - b->c == 'd');");1423 verifyFormat("x = ([a foo:bar] / b->c == 'd');");1424 verifyFormat("x = ([a foo:bar] % b->c == 'd');");1425 verifyFormat("x = ([a foo:bar] | b->c == 'd');");1426 verifyFormat("x = ([a foo:bar] || b->c == 'd');");1427 verifyFormat("x = ([a foo:bar] && b->c == 'd');");1428 verifyFormat("x = ([a foo:bar] == b->c == 'd');");1429 verifyFormat("x = ([a foo:bar] != b->c == 'd');");1430 verifyFormat("x = ([a foo:bar] <= b->c == 'd');");1431 verifyFormat("x = ([a foo:bar] >= b->c == 'd');");1432 verifyFormat("x = ([a foo:bar] << b->c == 'd');");1433 verifyFormat("x = ([a foo:bar] ? b->c == 'd' : 'e');");1434 // FIXME: The following are wrongly classified as C++ lambda expressions.1435 // For example this code:1436 // x = ([a foo:bar] & b->c == 'd');1437 // is formatted as:1438 // x = ([a foo:bar] & b -> c == 'd');1439 // verifyFormat("x = ([a foo:bar] & b->c == 'd');");1440 // verifyFormat("x = ([a foo:bar] > b->c == 'd');");1441 // verifyFormat("x = ([a foo:bar] < b->c == 'd');");1442 // verifyFormat("x = ([a foo:bar] >> b->c == 'd');");1443}1444 1445TEST_F(FormatTestObjC, DisambiguatesCallsFromStructuredBindings) {1446 verifyFormat("int f() {\n"1447 " if (a && [f arg])\n"1448 " return 0;\n"1449 "}");1450 verifyFormat("int f() {\n"1451 " if (a & [f arg])\n"1452 " return 0;\n"1453 "}");1454 verifyFormat("int f() {\n"1455 " for (auto &[elem] : list)\n"1456 " return 0;\n"1457 "}");1458 verifyFormat("int f() {\n"1459 " for (auto &&[elem] : list)\n"1460 " return 0;\n"1461 "}");1462 verifyFormat(1463 "int f() {\n"1464 " for (auto /**/ const /**/ volatile /**/ && /**/ [elem] : list)\n"1465 " return 0;\n"1466 "}");1467}1468 1469TEST_F(FormatTestObjC, BreakLineBeforeNestedBlockParam) {1470 Style = getGoogleStyle(FormatStyle::LK_ObjC);1471 Style.ObjCBreakBeforeNestedBlockParam = false;1472 Style.ColumnLimit = 0;1473 1474 verifyFormat("[self.test1 t:self callback:^(typeof(self) self, NSNumber *u, "1475 "NSNumber *v) {\n"1476 " u = v;\n"1477 "}]");1478 1479 verifyFormat("[self.test1 t:self w:self callback:^(typeof(self) self, "1480 "NSNumber *u, NSNumber *v) {\n"1481 " u = v;\n"1482 "}]");1483 1484 verifyFormat("[self.test1 t:self w:self callback:^(typeof(self) self, "1485 "NSNumber *u, NSNumber *v) {\n"1486 " u = c;\n"1487 "} w:self callback2:^(typeof(self) self, NSNumber *a, NSNumber "1488 "*b, NSNumber *c) {\n"1489 " b = c;\n"1490 "}]");1491 verifyFormat("[self.test1 t:self w:self callback:^(typeof(self) self, "1492 "NSNumber *u, NSNumber *v) {\n"1493 " u = v;\n"1494 "} z:self]");1495 1496 Style.ColumnLimit = 80;1497 verifyFormat(1498 "[self.test_method a:self b:self\n"1499 " callback:^(typeof(self) self, NSNumber *u, NSNumber *v) {\n"1500 " u = v;\n"1501 " }]");1502 1503 verifyFormat("[self block:^(void) {\n"1504 " doStuff();\n"1505 "} completionHandler:^(void) {\n"1506 " doStuff();\n"1507 " [self block:^(void) {\n"1508 " doStuff();\n"1509 " } completionHandler:^(void) {\n"1510 " doStuff();\n"1511 " }];\n"1512 "}];");1513 1514 Style.ColumnLimit = 0;1515 verifyFormat("[[SessionService sharedService] "1516 "loadWindowWithCompletionBlock:^(SessionWindow *window) {\n"1517 " if (window) {\n"1518 " [self windowDidLoad:window];\n"1519 " } else {\n"1520 " [self errorLoadingWindow];\n"1521 " }\n"1522 "}];");1523 verifyFormat("[controller test:^{\n"1524 " doStuff();\n"1525 "} withTimeout:5 completionHandler:^{\n"1526 " doStuff();\n"1527 "}];");1528 verifyFormat(1529 "[self setupTextFieldSignals:@[\n"1530 " self.documentWidthField,\n"1531 " self.documentHeightField,\n"1532 "] solver:^(NSTextField *textField) {\n"1533 " return [self.representedObject solveEquationForTextField:textField];\n"1534 "}];");1535}1536 1537TEST_F(FormatTestObjC, IfNotUnlikely) {1538 Style = getGoogleStyle(FormatStyle::LK_ObjC);1539 1540 verifyFormat("if (argc < 5) [obj func:arg];");1541 verifyFormat("if (argc < 5) [[obj1 method1:arg1] method2:arg2];");1542 verifyFormat("if (argc < 5) [[foo bar] baz:i[0]];");1543 verifyFormat("if (argc < 5) [[foo bar] baz:i[0]][1];");1544 1545 verifyFormat("if (argc < 5)\n"1546 " [obj func:arg];\n"1547 "else\n"1548 " [obj func:arg2];");1549 1550 verifyFormat("if (argc < 5) [[unlikely]]\n"1551 " [obj func:arg];\n"1552 "else [[likely]]\n"1553 " [obj func:arg2];");1554}1555 1556TEST_F(FormatTestObjC, AttributesOnObjCDecl) {1557 Style.AttributeMacros.push_back("ATTRIBUTE_MACRO");1558 1559 // Check '__attribute__' macro directly.1560 verifyFormat("__attribute__((objc_subclassing_restricted))\n"1561 "@interface Foo\n"1562 "@end");1563 verifyFormat("__attribute__((objc_subclassing_restricted))\n"1564 "@protocol Foo\n"1565 "@end");1566 verifyFormat("__attribute__((objc_subclassing_restricted))\n"1567 "@implementation Foo\n"1568 "@end");1569 1570 // Check AttributeMacro gets treated the same, with or without parentheses.1571 verifyFormat("ATTRIBUTE_MACRO\n"1572 "@interface Foo\n"1573 "@end");1574 verifyFormat("ATTRIBUTE_MACRO(X)\n"1575 "@interface Foo\n"1576 "@end");1577 1578 // Indenter also needs to understand multiple attribute macros.1579 // Try each of the three kinds paired with each of the other kind.1580 1581 // Column limit, but no reflow.1582 verifyFormat("ATTRIBUTE_MACRO(X) ATTRIBUTE_MACRO\n"1583 "@interface Foo\n"1584 "@end");1585 verifyFormat("ATTRIBUTE_MACRO ATTRIBUTE_MACRO(X)\n"1586 "@interface Foo\n"1587 "@end");1588 verifyFormat("__attribute__((X)) ATTRIBUTE_MACRO\n"1589 "@interface Foo\n"1590 "@end");1591 verifyFormat("ATTRIBUTE_MACRO __attribute__((X))\n"1592 "@interface Foo\n"1593 "@end");1594 verifyFormat("__attribute__((X)) ATTRIBUTE_MACRO(X)\n"1595 "@interface Foo\n"1596 "@end");1597 verifyFormat("ATTRIBUTE_MACRO(X) __attribute__((X))\n"1598 "@interface Foo\n"1599 "@end");1600 1601 // Column limit that requires reflow.1602 Style.ColumnLimit = 30;1603 verifyFormat("ATTRIBUTE_MACRO(X)\n"1604 "ATTRIBUTE_MACRO\n"1605 "@interface Foo\n"1606 "@end");1607 verifyFormat("ATTRIBUTE_MACRO\n"1608 "ATTRIBUTE_MACRO(X)\n"1609 "@interface Foo\n"1610 "@end");1611 verifyFormat("__attribute__((X))\n"1612 "ATTRIBUTE_MACRO\n"1613 "@interface Foo\n"1614 "@end");1615 verifyFormat("ATTRIBUTE_MACRO\n"1616 "__attribute__((X))\n"1617 "@interface Foo\n"1618 "@end");1619 verifyFormat("__attribute__((X))\n"1620 "ATTRIBUTE_MACRO(X)\n"1621 "@interface Foo\n"1622 "@end");1623 verifyFormat("ATTRIBUTE_MACRO(X)\n"1624 "__attribute__((X))\n"1625 "@interface Foo\n"1626 "@end");1627 1628 // No column limit1629 Style.ColumnLimit = 0;1630 verifyFormat("ATTRIBUTE_MACRO(X) ATTRIBUTE_MACRO\n"1631 "@interface Foo\n"1632 "@end");1633 verifyFormat("ATTRIBUTE_MACRO ATTRIBUTE_MACRO(X)\n"1634 "@interface Foo\n"1635 "@end");1636 verifyFormat("__attribute__((X)) ATTRIBUTE_MACRO\n"1637 "@interface Foo\n"1638 "@end");1639 verifyFormat("ATTRIBUTE_MACRO __attribute__((X))\n"1640 "@interface Foo\n"1641 "@end");1642 verifyFormat("__attribute__((X)) ATTRIBUTE_MACRO(X)\n"1643 "@interface Foo\n"1644 "@end");1645 verifyFormat("ATTRIBUTE_MACRO(X) __attribute__((X))\n"1646 "@interface Foo\n"1647 "@end");1648}1649 1650TEST_F(FormatTestObjC, AttributesOnObjCMethodDecl) {1651 Style.AttributeMacros.push_back("ATTRIBUTE_MACRO");1652 1653 // Check '__attribute__' macro directly.1654 verifyFormat("- (id)init __attribute__((objc_designated_initializer));");1655 1656 // Check AttributeMacro gets treated the same, with or without parentheses.1657 verifyFormat("- (id)init ATTRIBUTE_MACRO;");1658 verifyFormat("- (id)init ATTRIBUTE_MACRO(X);");1659 1660 // Indenter also needs to understand multiple attribute macros.1661 1662 // Column limit (default), but no reflow.1663 verifyFormat("- (id)init ATTRIBUTE_MACRO(X) ATTRIBUTE_MACRO;");1664 verifyFormat("- (id)init ATTRIBUTE_MACRO ATTRIBUTE_MACRO(X);");1665 verifyFormat("- (id)init __attribute__((X)) ATTRIBUTE_MACRO;");1666 verifyFormat("- (id)init ATTRIBUTE_MACRO __attribute__((X));");1667 verifyFormat("- (id)init __attribute__((X)) ATTRIBUTE_MACRO(X);");1668 verifyFormat("- (id)init ATTRIBUTE_MACRO(X) __attribute__((X));");1669 1670 // Column limit that requires reflow.1671 Style.ColumnLimit = 30;1672 1673 // Reflow after method name.1674 verifyFormat("- (id)initWithReallyLongName\n"1675 " __attribute__((X))\n"1676 " ATTRIBUTE_MACRO;");1677 verifyFormat("- (id)initWithReallyLongName\n"1678 " ATTRIBUTE_MACRO(X)\n"1679 " ATTRIBUTE_MACRO;");1680 verifyFormat("- (id)initWithReallyLongName\n"1681 " ATTRIBUTE_MACRO\n"1682 " ATTRIBUTE_MACRO;");1683 // Reflow after first macro.1684 // FIXME: these should indent but don't.1685#if 01686 verifyFormat("- (id)init ATTRIBUTE_MACRO(X)\n"1687 " ATTRIBUTE_MACRO;");1688 verifyFormat("- (id)init ATTRIBUTE_MACRO\n"1689 " ATTRIBUTE_MACRO(X);");1690 verifyFormat("- (id)init __attribute__((X))\n"1691 " ATTRIBUTE_MACRO;");1692 verifyFormat("- (id)init ATTRIBUTE_MACRO\n"1693 " __attribute__((X));");1694 verifyFormat("- (id)init __attribute__((X))\n"1695 " ATTRIBUTE_MACRO(X);");1696 verifyFormat("- (id)init ATTRIBUTE_MACRO(X)\n"1697 " __attribute__((X));");1698#endif1699 1700 // No column limit.1701 Style.ColumnLimit = 0;1702 verifyFormat("- (id)init ATTRIBUTE_MACRO(X) ATTRIBUTE_MACRO;");1703 verifyFormat("- (id)init ATTRIBUTE_MACRO ATTRIBUTE_MACRO(X);");1704 verifyFormat("- (id)init __attribute__((X)) ATTRIBUTE_MACRO;");1705 verifyFormat("- (id)init ATTRIBUTE_MACRO __attribute__((X));");1706 verifyFormat("- (id)init __attribute__((X)) ATTRIBUTE_MACRO(X);");1707 verifyFormat("- (id)init ATTRIBUTE_MACRO(X) __attribute__((X));");1708}1709 1710TEST_F(FormatTestObjC, AttributesOnObjCProperty) {1711 Style.AttributeMacros.push_back("ATTRIBUTE_MACRO");1712 1713 // Check '__attribute__' macro directly.1714 verifyFormat("@property(weak) id delegate "1715 "__attribute__((objc_designated_initializer));");1716 1717 // Check AttributeMacro gets treated the same, with or without parentheses.1718 verifyFormat("@property(weak) id delegate ATTRIBUTE_MACRO;");1719 verifyFormat("@property(weak) id delegate ATTRIBUTE_MACRO(X);");1720 1721 // Indenter also needs to understand multiple attribute macros.1722 1723 // Column limit (default), but no reflow.1724 verifyFormat(1725 "@property(weak) id delegate ATTRIBUTE_MACRO(X) ATTRIBUTE_MACRO;");1726 verifyFormat(1727 "@property(weak) id delegate ATTRIBUTE_MACRO ATTRIBUTE_MACRO(X);");1728 verifyFormat(1729 "@property(weak) id delegate __attribute__((X)) ATTRIBUTE_MACRO;");1730 verifyFormat(1731 "@property(weak) id delegate ATTRIBUTE_MACRO __attribute__((X));");1732 verifyFormat(1733 "@property(weak) id delegate __attribute__((X)) ATTRIBUTE_MACRO(X);");1734 verifyFormat(1735 "@property(weak) id delegate ATTRIBUTE_MACRO(X) __attribute__((X));");1736 1737 // Column limit that requires reflow.1738 Style.ColumnLimit = 50;1739 1740 // Reflow after method name.1741 verifyFormat("@property(weak) id delegateWithLongName\n"1742 " __attribute__((X)) ATTRIBUTE_MACRO;");1743 verifyFormat("@property(weak) id delegateWithLongName\n"1744 " ATTRIBUTE_MACRO(X) ATTRIBUTE_MACRO;");1745 verifyFormat("@property(weak) id delegateWithLongName\n"1746 " ATTRIBUTE_MACRO ATTRIBUTE_MACRO;");1747 // Reflow after first macro.1748 // FIXME: these should indent but don't.1749#if 01750 verifyFormat("@property(weak) id delegate ATTRIBUTE_MACRO(X)\n"1751 " ATTRIBUTE_MACRO;");1752 verifyFormat("@property(weak) id delegate ATTRIBUTE_MACRO\n"1753 " ATTRIBUTE_MACRO(X);");1754 verifyFormat("@property(weak) id delegate __attribute__((X))\n"1755 " ATTRIBUTE_MACRO;");1756 verifyFormat("@property(weak) id delegate ATTRIBUTE_MACRO\n"1757 " __attribute__((X));");1758 verifyFormat("@property(weak) id delegate __attribute__((X))\n"1759 " ATTRIBUTE_MACRO(X);");1760 verifyFormat("@property(weak) id delegate ATTRIBUTE_MACRO(X)\n"1761 " __attribute__((X));");1762#endif1763 1764 // No column limit.1765 Style.ColumnLimit = 0;1766 verifyFormat(1767 "@property(weak) id delegate ATTRIBUTE_MACRO(X) ATTRIBUTE_MACRO;");1768 verifyFormat(1769 "@property(weak) id delegate ATTRIBUTE_MACRO ATTRIBUTE_MACRO(X);");1770 verifyFormat(1771 "@property(weak) id delegate __attribute__((X)) ATTRIBUTE_MACRO;");1772 verifyFormat(1773 "@property(weak) id delegate ATTRIBUTE_MACRO __attribute__((X));");1774 verifyFormat(1775 "@property(weak) id delegate __attribute__((X)) ATTRIBUTE_MACRO(X);");1776 verifyFormat(1777 "@property(weak) id delegate ATTRIBUTE_MACRO(X) __attribute__((X));");1778}1779 1780} // end namespace1781} // namespace test1782} // end namespace format1783} // end namespace clang1784