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