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