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