1 //===- unittest/Format/FormatTestObjC.cpp - Formatting unit tests----------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "clang/Format/Format.h" 11 12 #include "../Tooling/ReplacementTest.h" 13 #include "FormatTestUtils.h" 14 15 #include "clang/Frontend/TextDiagnosticPrinter.h" 16 #include "llvm/Support/Debug.h" 17 #include "llvm/Support/MemoryBuffer.h" 18 #include "gtest/gtest.h" 19 20 #define DEBUG_TYPE "format-test" 21 22 using clang::tooling::ReplacementTest; 23 using clang::tooling::toReplacements; 24 25 namespace clang { 26 namespace format { 27 namespace { 28 29 class FormatTestObjC : public ::testing::Test { 30 protected: 31 FormatTestObjC() { 32 Style = getLLVMStyle(); 33 Style.Language = FormatStyle::LK_ObjC; 34 } 35 36 enum IncompleteCheck { 37 IC_ExpectComplete, 38 IC_ExpectIncomplete, 39 IC_DoNotCheck 40 }; 41 42 std::string format(llvm::StringRef Code, 43 IncompleteCheck CheckIncomplete = IC_ExpectComplete) { 44 DEBUG(llvm::errs() << "---\n"); 45 DEBUG(llvm::errs() << Code << "\n\n"); 46 std::vector<tooling::Range> Ranges(1, tooling::Range(0, Code.size())); 47 bool IncompleteFormat = false; 48 tooling::Replacements Replaces = 49 reformat(Style, Code, Ranges, "<stdin>", &IncompleteFormat); 50 if (CheckIncomplete != IC_DoNotCheck) { 51 bool ExpectedIncompleteFormat = CheckIncomplete == IC_ExpectIncomplete; 52 EXPECT_EQ(ExpectedIncompleteFormat, IncompleteFormat) << Code << "\n\n"; 53 } 54 auto Result = applyAllReplacements(Code, Replaces); 55 EXPECT_TRUE(static_cast<bool>(Result)); 56 DEBUG(llvm::errs() << "\n" << *Result << "\n\n"); 57 return *Result; 58 } 59 60 void verifyFormat(StringRef Code) { 61 EXPECT_EQ(Code.str(), format(test::messUp(Code))); 62 } 63 64 void verifyIncompleteFormat(StringRef Code) { 65 EXPECT_EQ(Code.str(), format(test::messUp(Code), IC_ExpectIncomplete)); 66 } 67 68 FormatStyle Style; 69 }; 70 71 TEST_F(FormatTestObjC, DetectsObjCInHeaders) { 72 Style = getStyle("LLVM", "a.h", "none", "@interface\n" 73 "- (id)init;"); 74 EXPECT_EQ(FormatStyle::LK_ObjC, Style.Language); 75 Style = getStyle("LLVM", "a.h", "none", "@interface\n" 76 "+ (id)init;"); 77 EXPECT_EQ(FormatStyle::LK_ObjC, Style.Language); 78 79 // No recognizable ObjC. 80 Style = getStyle("LLVM", "a.h", "none", "void f() {}"); 81 EXPECT_EQ(FormatStyle::LK_Cpp, Style.Language); 82 } 83 84 TEST_F(FormatTestObjC, FormatObjCTryCatch) { 85 verifyFormat("@try {\n" 86 " f();\n" 87 "} @catch (NSException e) {\n" 88 " @throw;\n" 89 "} @finally {\n" 90 " exit(42);\n" 91 "}"); 92 verifyFormat("DEBUG({\n" 93 " @try {\n" 94 " } @finally {\n" 95 " }\n" 96 "});\n"); 97 } 98 99 TEST_F(FormatTestObjC, FormatObjCAutoreleasepool) { 100 verifyFormat("@autoreleasepool {\n" 101 " f();\n" 102 "}\n" 103 "@autoreleasepool {\n" 104 " f();\n" 105 "}\n"); 106 Style.BreakBeforeBraces = FormatStyle::BS_Allman; 107 verifyFormat("@autoreleasepool\n" 108 "{\n" 109 " f();\n" 110 "}\n" 111 "@autoreleasepool\n" 112 "{\n" 113 " f();\n" 114 "}\n"); 115 } 116 117 TEST_F(FormatTestObjC, FormatObjCInterface) { 118 verifyFormat("@interface Foo : NSObject <NSSomeDelegate> {\n" 119 "@public\n" 120 " int field1;\n" 121 "@protected\n" 122 " int field2;\n" 123 "@private\n" 124 " int field3;\n" 125 "@package\n" 126 " int field4;\n" 127 "}\n" 128 "+ (id)init;\n" 129 "@end"); 130 131 verifyFormat("@interface /* wait for it */ Foo\n" 132 "+ (id)init;\n" 133 "// Look, a comment!\n" 134 "- (int)answerWith:(int)i;\n" 135 "@end"); 136 137 verifyFormat("@interface Foo\n" 138 "@end\n" 139 "@interface Bar\n" 140 "@end"); 141 142 verifyFormat("@interface Foo : Bar\n" 143 "+ (id)init;\n" 144 "@end"); 145 146 verifyFormat("@interface Foo : /**/ Bar /**/ <Baz, /**/ Quux>\n" 147 "+ (id)init;\n" 148 "@end"); 149 150 verifyFormat("@interface Foo (HackStuff)\n" 151 "+ (id)init;\n" 152 "@end"); 153 154 verifyFormat("@interface Foo ()\n" 155 "+ (id)init;\n" 156 "@end"); 157 158 verifyFormat("@interface Foo (HackStuff) <MyProtocol>\n" 159 "+ (id)init;\n" 160 "@end"); 161 162 verifyFormat("@interface Foo {\n" 163 " int _i;\n" 164 "}\n" 165 "+ (id)init;\n" 166 "@end"); 167 168 verifyFormat("@interface Foo : Bar {\n" 169 " int _i;\n" 170 "}\n" 171 "+ (id)init;\n" 172 "@end"); 173 174 verifyFormat("@interface Foo : Bar <Baz, Quux> {\n" 175 " int _i;\n" 176 "}\n" 177 "+ (id)init;\n" 178 "@end"); 179 180 verifyFormat("@interface Foo (HackStuff) {\n" 181 " int _i;\n" 182 "}\n" 183 "+ (id)init;\n" 184 "@end"); 185 186 verifyFormat("@interface Foo () {\n" 187 " int _i;\n" 188 "}\n" 189 "+ (id)init;\n" 190 "@end"); 191 192 verifyFormat("@interface Foo (HackStuff) <MyProtocol> {\n" 193 " int _i;\n" 194 "}\n" 195 "+ (id)init;\n" 196 "@end"); 197 198 Style = getGoogleStyle(FormatStyle::LK_ObjC); 199 verifyFormat("@interface Foo : NSObject<NSSomeDelegate> {\n" 200 " @public\n" 201 " int field1;\n" 202 " @protected\n" 203 " int field2;\n" 204 " @private\n" 205 " int field3;\n" 206 " @package\n" 207 " int field4;\n" 208 "}\n" 209 "+ (id)init;\n" 210 "@end"); 211 verifyFormat("@interface Foo : Bar<Baz, Quux>\n" 212 "+ (id)init;\n" 213 "@end"); 214 verifyFormat("@interface Foo (HackStuff)<MyProtocol>\n" 215 "+ (id)init;\n" 216 "@end"); 217 Style.BinPackParameters = false; 218 Style.ColumnLimit = 80; 219 verifyFormat("@interface aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ()<\n" 220 " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" 221 " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" 222 " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" 223 " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa> {\n" 224 "}"); 225 } 226 227 TEST_F(FormatTestObjC, FormatObjCImplementation) { 228 verifyFormat("@implementation Foo : NSObject {\n" 229 "@public\n" 230 " int field1;\n" 231 "@protected\n" 232 " int field2;\n" 233 "@private\n" 234 " int field3;\n" 235 "@package\n" 236 " int field4;\n" 237 "}\n" 238 "+ (id)init {\n}\n" 239 "@end"); 240 241 verifyFormat("@implementation Foo\n" 242 "+ (id)init {\n" 243 " if (true)\n" 244 " return nil;\n" 245 "}\n" 246 "// Look, a comment!\n" 247 "- (int)answerWith:(int)i {\n" 248 " return i;\n" 249 "}\n" 250 "+ (int)answerWith:(int)i {\n" 251 " return i;\n" 252 "}\n" 253 "@end"); 254 255 verifyFormat("@implementation Foo\n" 256 "@end\n" 257 "@implementation Bar\n" 258 "@end"); 259 260 EXPECT_EQ("@implementation Foo : Bar\n" 261 "+ (id)init {\n}\n" 262 "- (void)foo {\n}\n" 263 "@end", 264 format("@implementation Foo : Bar\n" 265 "+(id)init{}\n" 266 "-(void)foo{}\n" 267 "@end")); 268 269 verifyFormat("@implementation Foo {\n" 270 " int _i;\n" 271 "}\n" 272 "+ (id)init {\n}\n" 273 "@end"); 274 275 verifyFormat("@implementation Foo : Bar {\n" 276 " int _i;\n" 277 "}\n" 278 "+ (id)init {\n}\n" 279 "@end"); 280 281 verifyFormat("@implementation Foo (HackStuff)\n" 282 "+ (id)init {\n}\n" 283 "@end"); 284 verifyFormat("@implementation ObjcClass\n" 285 "- (void)method;\n" 286 "{}\n" 287 "@end"); 288 289 Style = getGoogleStyle(FormatStyle::LK_ObjC); 290 verifyFormat("@implementation Foo : NSObject {\n" 291 " @public\n" 292 " int field1;\n" 293 " @protected\n" 294 " int field2;\n" 295 " @private\n" 296 " int field3;\n" 297 " @package\n" 298 " int field4;\n" 299 "}\n" 300 "+ (id)init {\n}\n" 301 "@end"); 302 } 303 304 TEST_F(FormatTestObjC, FormatObjCProtocol) { 305 verifyFormat("@protocol Foo\n" 306 "@property(weak) id delegate;\n" 307 "- (NSUInteger)numberOfThings;\n" 308 "@end"); 309 310 verifyFormat("@protocol MyProtocol <NSObject>\n" 311 "- (NSUInteger)numberOfThings;\n" 312 "@end"); 313 314 verifyFormat("@protocol Foo;\n" 315 "@protocol Bar;\n"); 316 317 verifyFormat("@protocol Foo\n" 318 "@end\n" 319 "@protocol Bar\n" 320 "@end"); 321 322 verifyFormat("@protocol myProtocol\n" 323 "- (void)mandatoryWithInt:(int)i;\n" 324 "@optional\n" 325 "- (void)optional;\n" 326 "@required\n" 327 "- (void)required;\n" 328 "@optional\n" 329 "@property(assign) int madProp;\n" 330 "@end\n"); 331 332 verifyFormat("@property(nonatomic, assign, readonly)\n" 333 " int *looooooooooooooooooooooooooooongNumber;\n" 334 "@property(nonatomic, assign, readonly)\n" 335 " NSString *looooooooooooooooooooooooooooongName;"); 336 337 verifyFormat("@implementation PR18406\n" 338 "}\n" 339 "@end"); 340 341 Style = getGoogleStyle(FormatStyle::LK_ObjC); 342 verifyFormat("@protocol MyProtocol<NSObject>\n" 343 "- (NSUInteger)numberOfThings;\n" 344 "@end"); 345 } 346 347 TEST_F(FormatTestObjC, FormatObjCMethodDeclarations) { 348 verifyFormat("- (void)doSomethingWith:(GTMFoo *)theFoo\n" 349 " rect:(NSRect)theRect\n" 350 " interval:(float)theInterval {\n" 351 "}"); 352 verifyFormat("- (void)shortf:(GTMFoo *)theFoo\n" 353 " longKeyword:(NSRect)theRect\n" 354 " longerKeyword:(float)theInterval\n" 355 " error:(NSError **)theError {\n" 356 "}"); 357 verifyFormat("- (void)shortf:(GTMFoo *)theFoo\n" 358 " longKeyword:(NSRect)theRect\n" 359 " evenLongerKeyword:(float)theInterval\n" 360 " error:(NSError **)theError {\n" 361 "}"); 362 Style.ColumnLimit = 60; 363 verifyFormat("- (instancetype)initXxxxxx:(id<x>)x\n" 364 " y:(id<yyyyyyyyyyyyyyyyyyyy>)y\n" 365 " NS_DESIGNATED_INITIALIZER;"); 366 verifyFormat("- (void)drawRectOn:(id)surface\n" 367 " ofSize:(size_t)height\n" 368 " :(size_t)width;"); 369 370 // Continuation indent width should win over aligning colons if the function 371 // name is long. 372 Style = getGoogleStyle(FormatStyle::LK_ObjC); 373 Style.ColumnLimit = 40; 374 Style.IndentWrappedFunctionNames = true; 375 verifyFormat("- (void)shortf:(GTMFoo *)theFoo\n" 376 " dontAlignNamef:(NSRect)theRect {\n" 377 "}"); 378 379 // Make sure we don't break aligning for short parameter names. 380 verifyFormat("- (void)shortf:(GTMFoo *)theFoo\n" 381 " aShortf:(NSRect)theRect {\n" 382 "}"); 383 384 // Format pairs correctly. 385 Style.ColumnLimit = 80; 386 verifyFormat("- (void)drawRectOn:(id)surface\n" 387 " ofSize:(aaaaaaaa)height\n" 388 " :(size_t)width\n" 389 " atOrigin:(size_t)x\n" 390 " :(size_t)y\n" 391 " aaaaa:(a)yyy\n" 392 " bbb:(d)cccc;"); 393 verifyFormat("- (void)drawRectOn:(id)surface ofSize:(aaa)height:(bbb)width;"); 394 } 395 396 TEST_F(FormatTestObjC, FormatObjCMethodExpr) { 397 verifyFormat("[foo bar:baz];"); 398 verifyFormat("return [foo bar:baz];"); 399 verifyFormat("return (a)[foo bar:baz];"); 400 verifyFormat("f([foo bar:baz]);"); 401 verifyFormat("f(2, [foo bar:baz]);"); 402 verifyFormat("f(2, a ? b : c);"); 403 verifyFormat("[[self initWithInt:4] bar:[baz quux:arrrr]];"); 404 405 // Unary operators. 406 verifyFormat("int a = +[foo bar:baz];"); 407 verifyFormat("int a = -[foo bar:baz];"); 408 verifyFormat("int a = ![foo bar:baz];"); 409 verifyFormat("int a = ~[foo bar:baz];"); 410 verifyFormat("int a = ++[foo bar:baz];"); 411 verifyFormat("int a = --[foo bar:baz];"); 412 verifyFormat("int a = sizeof [foo bar:baz];"); 413 verifyFormat("int a = alignof [foo bar:baz];"); 414 verifyFormat("int a = &[foo bar:baz];"); 415 verifyFormat("int a = *[foo bar:baz];"); 416 // FIXME: Make casts work, without breaking f()[4]. 417 // verifyFormat("int a = (int)[foo bar:baz];"); 418 // verifyFormat("return (int)[foo bar:baz];"); 419 // verifyFormat("(void)[foo bar:baz];"); 420 verifyFormat("return (MyType *)[self.tableView cellForRowAtIndexPath:cell];"); 421 422 // Binary operators. 423 verifyFormat("[foo bar:baz], [foo bar:baz];"); 424 verifyFormat("[foo bar:baz] = [foo bar:baz];"); 425 verifyFormat("[foo bar:baz] *= [foo bar:baz];"); 426 verifyFormat("[foo bar:baz] /= [foo bar:baz];"); 427 verifyFormat("[foo bar:baz] %= [foo bar:baz];"); 428 verifyFormat("[foo bar:baz] += [foo bar:baz];"); 429 verifyFormat("[foo bar:baz] -= [foo bar:baz];"); 430 verifyFormat("[foo bar:baz] <<= [foo bar:baz];"); 431 verifyFormat("[foo bar:baz] >>= [foo bar:baz];"); 432 verifyFormat("[foo bar:baz] &= [foo bar:baz];"); 433 verifyFormat("[foo bar:baz] ^= [foo bar:baz];"); 434 verifyFormat("[foo bar:baz] |= [foo bar:baz];"); 435 verifyFormat("[foo bar:baz] ? [foo bar:baz] : [foo bar:baz];"); 436 verifyFormat("[foo bar:baz] || [foo bar:baz];"); 437 verifyFormat("[foo bar:baz] && [foo bar:baz];"); 438 verifyFormat("[foo bar:baz] | [foo bar:baz];"); 439 verifyFormat("[foo bar:baz] ^ [foo bar:baz];"); 440 verifyFormat("[foo bar:baz] & [foo bar:baz];"); 441 verifyFormat("[foo bar:baz] == [foo bar:baz];"); 442 verifyFormat("[foo bar:baz] != [foo bar:baz];"); 443 verifyFormat("[foo bar:baz] >= [foo bar:baz];"); 444 verifyFormat("[foo bar:baz] <= [foo bar:baz];"); 445 verifyFormat("[foo bar:baz] > [foo bar:baz];"); 446 verifyFormat("[foo bar:baz] < [foo bar:baz];"); 447 verifyFormat("[foo bar:baz] >> [foo bar:baz];"); 448 verifyFormat("[foo bar:baz] << [foo bar:baz];"); 449 verifyFormat("[foo bar:baz] - [foo bar:baz];"); 450 verifyFormat("[foo bar:baz] + [foo bar:baz];"); 451 verifyFormat("[foo bar:baz] * [foo bar:baz];"); 452 verifyFormat("[foo bar:baz] / [foo bar:baz];"); 453 verifyFormat("[foo bar:baz] % [foo bar:baz];"); 454 // Whew! 455 456 verifyFormat("return in[42];"); 457 verifyFormat("for (auto v : in[1]) {\n}"); 458 verifyFormat("for (int i = 0; i < in[a]; ++i) {\n}"); 459 verifyFormat("for (int i = 0; in[a] < i; ++i) {\n}"); 460 verifyFormat("for (int i = 0; i < n; ++i, ++in[a]) {\n}"); 461 verifyFormat("for (int i = 0; i < n; ++i, in[a]++) {\n}"); 462 verifyFormat("for (int i = 0; i < f(in[a]); ++i, in[a]++) {\n}"); 463 verifyFormat("for (id foo in [self getStuffFor:bla]) {\n" 464 "}"); 465 verifyFormat("[self aaaaa:MACRO(a, b:, c:)];"); 466 verifyFormat("[self aaaaa:(1 + 2) bbbbb:3];"); 467 verifyFormat("[self aaaaa:(Type)a bbbbb:3];"); 468 469 verifyFormat("[self stuffWithInt:(4 + 2) float:4.5];"); 470 verifyFormat("[self stuffWithInt:a ? b : c float:4.5];"); 471 verifyFormat("[self stuffWithInt:a ? [self foo:bar] : c];"); 472 verifyFormat("[self stuffWithInt:a ? (e ? f : g) : c];"); 473 verifyFormat("[cond ? obj1 : obj2 methodWithParam:param]"); 474 verifyFormat("[button setAction:@selector(zoomOut:)];"); 475 verifyFormat("[color getRed:&r green:&g blue:&b alpha:&a];"); 476 477 verifyFormat("arr[[self indexForFoo:a]];"); 478 verifyFormat("throw [self errorFor:a];"); 479 verifyFormat("@throw [self errorFor:a];"); 480 481 verifyFormat("[(id)foo bar:(id)baz quux:(id)snorf];"); 482 verifyFormat("[(id)foo bar:(id) ? baz : quux];"); 483 verifyFormat("4 > 4 ? (id)a : (id)baz;"); 484 485 // This tests that the formatter doesn't break after "backing" but before ":", 486 // which would be at 80 columns. 487 verifyFormat( 488 "void f() {\n" 489 " if ((self = [super initWithContentRect:contentRect\n" 490 " styleMask:styleMask ?: otherMask\n" 491 " backing:NSBackingStoreBuffered\n" 492 " defer:YES]))"); 493 494 verifyFormat( 495 "[foo checkThatBreakingAfterColonWorksOk:\n" 496 " [bar ifItDoes:reduceOverallLineLengthLikeInThisCase]];"); 497 498 verifyFormat("[myObj short:arg1 // Force line break\n" 499 " longKeyword:arg2 != nil ? arg2 : @\"longKeyword\"\n" 500 " evenLongerKeyword:arg3 ?: @\"evenLongerKeyword\"\n" 501 " error:arg4];"); 502 verifyFormat( 503 "void f() {\n" 504 " popup_window_.reset([[RenderWidgetPopupWindow alloc]\n" 505 " initWithContentRect:NSMakeRect(origin_global.x, origin_global.y,\n" 506 " pos.width(), pos.height())\n" 507 " styleMask:NSBorderlessWindowMask\n" 508 " backing:NSBackingStoreBuffered\n" 509 " defer:NO]);\n" 510 "}"); 511 verifyFormat("[contentsContainer replaceSubview:[subviews objectAtIndex:0]\n" 512 " with:contentsNativeView];"); 513 514 verifyFormat( 515 "[pboard addTypes:[NSArray arrayWithObject:kBookmarkButtonDragType]\n" 516 " owner:nillllll];"); 517 518 verifyFormat( 519 "[pboard setData:[NSData dataWithBytes:&button length:sizeof(button)]\n" 520 " forType:kBookmarkButtonDragType];"); 521 522 verifyFormat("[defaultCenter addObserver:self\n" 523 " selector:@selector(willEnterFullscreen)\n" 524 " name:kWillEnterFullscreenNotification\n" 525 " object:nil];"); 526 verifyFormat("[image_rep drawInRect:drawRect\n" 527 " fromRect:NSZeroRect\n" 528 " operation:NSCompositeCopy\n" 529 " fraction:1.0\n" 530 " respectFlipped:NO\n" 531 " hints:nil];"); 532 verifyFormat("[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" 533 " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa];"); 534 verifyFormat("[aaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaa)\n" 535 " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa];"); 536 verifyFormat("[aaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaa[aaaaaaaaaaaaaaaaaaaaa]\n" 537 " aaaaaaaaaaaaaaaaaaaaaa];"); 538 539 verifyFormat( 540 "scoped_nsobject<NSTextField> message(\n" 541 " // The frame will be fixed up when |-setMessageText:| is called.\n" 542 " [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 0, 0)]);"); 543 verifyFormat("[self aaaaaa:bbbbbbbbbbbbb\n" 544 " aaaaaaaaaa:bbbbbbbbbbbbbbbbb\n" 545 " aaaaa:bbbbbbbbbbb + bbbbbbbbbbbb\n" 546 " aaaa:bbb];"); 547 verifyFormat("[self param:function( //\n" 548 " parameter)]"); 549 verifyFormat( 550 "[self aaaaaaaaaa:aaaaaaaaaaaaaaa | aaaaaaaaaaaaaaa | aaaaaaaaaaaaaaa |\n" 551 " aaaaaaaaaaaaaaa | aaaaaaaaaaaaaaa | aaaaaaaaaaaaaaa |\n" 552 " aaaaaaaaaaaaaaa | aaaaaaaaaaaaaaa];"); 553 554 // Variadic parameters. 555 verifyFormat( 556 "NSArray *myStrings = [NSArray stringarray:@\"a\", @\"b\", nil];"); 557 verifyFormat( 558 "[self aaaaaaaaaaaaa:aaaaaaaaaaaaaaa, aaaaaaaaaaaaaaa, aaaaaaaaaaaaaaa,\n" 559 " aaaaaaaaaaaaaaa, aaaaaaaaaaaaaaa, aaaaaaaaaaaaaaa,\n" 560 " aaaaaaaaaaaaaaa, aaaaaaaaaaaaaaa];"); 561 verifyFormat("[self // break\n" 562 " a:a\n" 563 " aaa:aaa];"); 564 verifyFormat("bool a = ([aaaaaaaa aaaaa] == aaaaaaaaaaaaaaaaa ||\n" 565 " [aaaaaaaa aaaaa] == aaaaaaaaaaaaaaaaaaaa);"); 566 567 // Formats pair-parameters. 568 verifyFormat("[I drawRectOn:surface ofSize:aa:bbb atOrigin:cc:dd];"); 569 verifyFormat("[I drawRectOn:surface //\n" 570 " ofSize:aa:bbb\n" 571 " atOrigin:cc:dd];"); 572 573 Style.ColumnLimit = 70; 574 verifyFormat( 575 "void f() {\n" 576 " popup_wdow_.reset([[RenderWidgetPopupWindow alloc]\n" 577 " iniithContentRect:NSMakRet(origin_global.x, origin_global.y,\n" 578 " pos.width(), pos.height())\n" 579 " syeMask:NSBorderlessWindowMask\n" 580 " bking:NSBackingStoreBuffered\n" 581 " der:NO]);\n" 582 "}"); 583 584 Style.ColumnLimit = 60; 585 verifyFormat("[call aaaaaaaa.aaaaaa.aaaaaaaa.aaaaaaaa.aaaaaaaa.aaaaaaaa\n" 586 " .aaaaaaaa];"); // FIXME: Indentation seems off. 587 // FIXME: This violates the column limit. 588 verifyFormat( 589 "[aaaaaaaaaaaaaaaaaaaaaaaaa\n" 590 " aaaaaaaaaaaaaaaaa:aaaaaaaa\n" 591 " aaa:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa];"); 592 593 Style = getChromiumStyle(FormatStyle::LK_ObjC); 594 Style.ColumnLimit = 80; 595 verifyFormat( 596 "void f() {\n" 597 " popup_window_.reset([[RenderWidgetPopupWindow alloc]\n" 598 " initWithContentRect:NSMakeRect(origin_global.x, origin_global.y,\n" 599 " pos.width(), pos.height())\n" 600 " styleMask:NSBorderlessWindowMask\n" 601 " backing:NSBackingStoreBuffered\n" 602 " defer:NO]);\n" 603 "}"); 604 } 605 606 TEST_F(FormatTestObjC, ObjCAt) { 607 verifyFormat("@autoreleasepool"); 608 verifyFormat("@catch"); 609 verifyFormat("@class"); 610 verifyFormat("@compatibility_alias"); 611 verifyFormat("@defs"); 612 verifyFormat("@dynamic"); 613 verifyFormat("@encode"); 614 verifyFormat("@end"); 615 verifyFormat("@finally"); 616 verifyFormat("@implementation"); 617 verifyFormat("@import"); 618 verifyFormat("@interface"); 619 verifyFormat("@optional"); 620 verifyFormat("@package"); 621 verifyFormat("@private"); 622 verifyFormat("@property"); 623 verifyFormat("@protected"); 624 verifyFormat("@protocol"); 625 verifyFormat("@public"); 626 verifyFormat("@required"); 627 verifyFormat("@selector"); 628 verifyFormat("@synchronized"); 629 verifyFormat("@synthesize"); 630 verifyFormat("@throw"); 631 verifyFormat("@try"); 632 633 EXPECT_EQ("@interface", format("@ interface")); 634 635 // The precise formatting of this doesn't matter, nobody writes code like 636 // this. 637 verifyFormat("@ /*foo*/ interface"); 638 } 639 640 TEST_F(FormatTestObjC, ObjCSnippets) { 641 verifyFormat("@autoreleasepool {\n" 642 " foo();\n" 643 "}"); 644 verifyFormat("@class Foo, Bar;"); 645 verifyFormat("@compatibility_alias AliasName ExistingClass;"); 646 verifyFormat("@dynamic textColor;"); 647 verifyFormat("char *buf1 = @encode(int *);"); 648 verifyFormat("char *buf1 = @encode(typeof(4 * 5));"); 649 verifyFormat("char *buf1 = @encode(int **);"); 650 verifyFormat("Protocol *proto = @protocol(p1);"); 651 verifyFormat("SEL s = @selector(foo:);"); 652 verifyFormat("@synchronized(self) {\n" 653 " f();\n" 654 "}"); 655 656 verifyFormat("@import foo.bar;\n" 657 "@import baz;"); 658 659 verifyFormat("@synthesize dropArrowPosition = dropArrowPosition_;"); 660 661 verifyFormat("@property(assign, nonatomic) CGFloat hoverAlpha;"); 662 verifyFormat("@property(assign, getter=isEditable) BOOL editable;"); 663 664 Style = getMozillaStyle(); 665 verifyFormat("@property (assign, getter=isEditable) BOOL editable;"); 666 verifyFormat("@property BOOL editable;"); 667 668 Style = getWebKitStyle(); 669 verifyFormat("@property (assign, getter=isEditable) BOOL editable;"); 670 verifyFormat("@property BOOL editable;"); 671 672 Style = getGoogleStyle(FormatStyle::LK_ObjC); 673 verifyFormat("@synthesize dropArrowPosition = dropArrowPosition_;"); 674 verifyFormat("@property(assign, getter=isEditable) BOOL editable;"); 675 } 676 677 TEST_F(FormatTestObjC, ObjCForIn) { 678 verifyFormat("- (void)test {\n" 679 " for (NSString *n in arrayOfStrings) {\n" 680 " foo(n);\n" 681 " }\n" 682 "}"); 683 verifyFormat("- (void)test {\n" 684 " for (NSString *n in (__bridge NSArray *)arrayOfStrings) {\n" 685 " foo(n);\n" 686 " }\n" 687 "}"); 688 } 689 690 TEST_F(FormatTestObjC, ObjCLiterals) { 691 verifyFormat("@\"String\""); 692 verifyFormat("@1"); 693 verifyFormat("@+4.8"); 694 verifyFormat("@-4"); 695 verifyFormat("@1LL"); 696 verifyFormat("@.5"); 697 verifyFormat("@'c'"); 698 verifyFormat("@true"); 699 700 verifyFormat("NSNumber *smallestInt = @(-INT_MAX - 1);"); 701 verifyFormat("NSNumber *piOverTwo = @(M_PI / 2);"); 702 verifyFormat("NSNumber *favoriteColor = @(Green);"); 703 verifyFormat("NSString *path = @(getenv(\"PATH\"));"); 704 705 verifyFormat("[dictionary setObject:@(1) forKey:@\"number\"];"); 706 } 707 708 TEST_F(FormatTestObjC, ObjCDictLiterals) { 709 verifyFormat("@{"); 710 verifyFormat("@{}"); 711 verifyFormat("@{@\"one\" : @1}"); 712 verifyFormat("return @{@\"one\" : @1;"); 713 verifyFormat("@{@\"one\" : @1}"); 714 715 verifyFormat("@{@\"one\" : @{@2 : @1}}"); 716 verifyFormat("@{\n" 717 " @\"one\" : @{@2 : @1},\n" 718 "}"); 719 720 verifyFormat("@{1 > 2 ? @\"one\" : @\"two\" : 1 > 2 ? @1 : @2}"); 721 verifyIncompleteFormat("[self setDict:@{}"); 722 verifyIncompleteFormat("[self setDict:@{@1 : @2}"); 723 verifyFormat("NSLog(@\"%@\", @{@1 : @2, @2 : @3}[@1]);"); 724 verifyFormat( 725 "NSDictionary *masses = @{@\"H\" : @1.0078, @\"He\" : @4.0026};"); 726 verifyFormat( 727 "NSDictionary *settings = @{AVEncoderKey : @(AVAudioQualityMax)};"); 728 729 verifyFormat("NSDictionary *d = @{\n" 730 " @\"nam\" : NSUserNam(),\n" 731 " @\"dte\" : [NSDate date],\n" 732 " @\"processInfo\" : [NSProcessInfo processInfo]\n" 733 "};"); 734 verifyFormat( 735 "@{\n" 736 " NSFontAttributeNameeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee : " 737 "regularFont,\n" 738 "};"); 739 verifyFormat( 740 "@{\n" 741 " NSFontAttributeNameeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee :\n" 742 " reeeeeeeeeeeeeeeeeeeeeeeegularFont,\n" 743 "};"); 744 745 // We should try to be robust in case someone forgets the "@". 746 verifyFormat("NSDictionary *d = {\n" 747 " @\"nam\" : NSUserNam(),\n" 748 " @\"dte\" : [NSDate date],\n" 749 " @\"processInfo\" : [NSProcessInfo processInfo]\n" 750 "};"); 751 verifyFormat("NSMutableDictionary *dictionary =\n" 752 " [NSMutableDictionary dictionaryWithDictionary:@{\n" 753 " aaaaaaaaaaaaaaaaaaaaa : aaaaaaaaaaaaa,\n" 754 " bbbbbbbbbbbbbbbbbb : bbbbb,\n" 755 " cccccccccccccccc : ccccccccccccccc\n" 756 " }];"); 757 758 // Ensure that casts before the key are kept on the same line as the key. 759 verifyFormat( 760 "NSDictionary *d = @{\n" 761 " (aaaaaaaa id)aaaaaaaaa : (aaaaaaaa id)aaaaaaaaaaaaaaaaaaaaaaaa,\n" 762 " (aaaaaaaa id)aaaaaaaaaaaaaa : (aaaaaaaa id)aaaaaaaaaaaaaa,\n" 763 "};"); 764 765 Style = getGoogleStyle(FormatStyle::LK_ObjC); 766 verifyFormat( 767 "@{\n" 768 " NSFontAttributeNameeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee : " 769 "regularFont,\n" 770 "};"); 771 } 772 773 TEST_F(FormatTestObjC, ObjCArrayLiterals) { 774 verifyIncompleteFormat("@["); 775 verifyFormat("@[]"); 776 verifyFormat( 777 "NSArray *array = @[ @\" Hey \", NSApp, [NSNumber numberWithInt:42] ];"); 778 verifyFormat("return @[ @3, @[], @[ @4, @5 ] ];"); 779 verifyFormat("NSArray *array = @[ [foo description] ];"); 780 781 verifyFormat( 782 "NSArray *some_variable = @[\n" 783 " aaaa == bbbbbbbbbbb ? @\"aaaaaaaaaaaa\" : @\"aaaaaaaaaaaaaa\",\n" 784 " @\"aaaaaaaaaaaaaaaaa\",\n" 785 " @\"aaaaaaaaaaaaaaaaa\",\n" 786 " @\"aaaaaaaaaaaaaaaaa\",\n" 787 "];"); 788 verifyFormat( 789 "NSArray *some_variable = @[\n" 790 " aaaa == bbbbbbbbbbb ? @\"aaaaaaaaaaaa\" : @\"aaaaaaaaaaaaaa\",\n" 791 " @\"aaaaaaaaaaaaaaaa\", @\"aaaaaaaaaaaaaaaa\", @\"aaaaaaaaaaaaaaaa\"\n" 792 "];"); 793 verifyFormat("NSArray *some_variable = @[\n" 794 " @\"aaaaaaaaaaaaaaaaa\",\n" 795 " @\"aaaaaaaaaaaaaaaaa\",\n" 796 " @\"aaaaaaaaaaaaaaaaa\",\n" 797 " @\"aaaaaaaaaaaaaaaaa\",\n" 798 "];"); 799 verifyFormat("NSArray *array = @[\n" 800 " @\"a\",\n" 801 " @\"a\",\n" // Trailing comma -> one per line. 802 "];"); 803 804 // We should try to be robust in case someone forgets the "@". 805 verifyFormat("NSArray *some_variable = [\n" 806 " @\"aaaaaaaaaaaaaaaaa\",\n" 807 " @\"aaaaaaaaaaaaaaaaa\",\n" 808 " @\"aaaaaaaaaaaaaaaaa\",\n" 809 " @\"aaaaaaaaaaaaaaaaa\",\n" 810 "];"); 811 verifyFormat( 812 "- (NSAttributedString *)attributedStringForSegment:(NSUInteger)segment\n" 813 " index:(NSUInteger)index\n" 814 " nonDigitAttributes:\n" 815 " (NSDictionary *)noDigitAttributes;"); 816 verifyFormat("[someFunction someLooooooooooooongParameter:@[\n" 817 " NSBundle.mainBundle.infoDictionary[@\"a\"]\n" 818 "]];"); 819 } 820 } // end namespace 821 } // end namespace format 822 } // end namespace clang 823