brintos

brintos / llvm-project-archived public Read only

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