Clang Project

clang_source_code/unittests/Format/FormatTestObjC.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-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "clang/Format/Format.h"
10
11#include "../Tooling/ReplacementTest.h"
12#include "FormatTestUtils.h"
13
14#include "clang/Frontend/TextDiagnosticPrinter.h"
15#include "llvm/Support/Debug.h"
16#include "llvm/Support/MemoryBuffer.h"
17#include "gtest/gtest.h"
18
19#define DEBUG_TYPE "format-test"
20
21using clang::tooling::ReplacementTest;
22
23namespace clang {
24namespace format {
25namespace {
26
27class FormatTestObjC : public ::testing::Test {
28protected:
29  FormatTestObjC() {
30    Style = getLLVMStyle();
31    Style.Language = FormatStyle::LK_ObjC;
32  }
33
34  enum StatusCheck {
35    SC_ExpectComplete,
36    SC_ExpectIncomplete,
37    SC_DoNotCheck
38  };
39
40  std::string format(llvm::StringRef Code,
41                     StatusCheck CheckComplete = SC_ExpectComplete) {
42    LLVM_DEBUG(llvm::errs() << "---\n");
43    LLVM_DEBUG(llvm::errs() << Code << "\n\n");
44    std::vector<tooling::RangeRanges(1, tooling::Range(0, Code.size()));
45    FormattingAttemptStatus Status;
46    tooling::Replacements Replaces =
47        reformat(Style, Code, Ranges, "<stdin>", &Status);
48    if (CheckComplete != SC_DoNotCheck) {
49      bool ExpectedCompleteFormat = CheckComplete == SC_ExpectComplete;
50      EXPECT_EQ(ExpectedCompleteFormat, Status.FormatComplete)
51          << Code << "\n\n";
52    }
53    auto Result = applyAllReplacements(Code, Replaces);
54    EXPECT_TRUE(static_cast<bool>(Result));
55    LLVM_DEBUG(llvm::errs() << "\n" << *Result << "\n\n");
56    return *Result;
57  }
58
59  void verifyFormat(StringRef Code) {
60    EXPECT_EQ(Code.str(), format(Code)) << "Expected code is not stable";
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
71TEST(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  Style = getStyle("{}""a.h""none""@interface Foo\n@end\n");
99  ASSERT_TRUE((bool)Style);
100  EXPECT_EQ(FormatStyle::LK_ObjC, Style->Language);
101
102  Style = getStyle("{}""a.h""none",
103                   "const int interface = 1;\nconst int end = 2;\n");
104  ASSERT_TRUE((bool)Style);
105  EXPECT_EQ(FormatStyle::LK_Cpp, Style->Language);
106
107  Style = getStyle("{}""a.h""none""@protocol Foo\n@end\n");
108  ASSERT_TRUE((bool)Style);
109  EXPECT_EQ(FormatStyle::LK_ObjC, Style->Language);
110
111  Style = getStyle("{}""a.h""none",
112                   "const int protocol = 1;\nconst int end = 2;\n");
113  ASSERT_TRUE((bool)Style);
114  EXPECT_EQ(FormatStyle::LK_Cpp, Style->Language);
115
116  Style =
117      getStyle("{}""a.h""none""typedef NS_ENUM(NSInteger, Foo) {};\n");
118  ASSERT_TRUE((bool)Style);
119  EXPECT_EQ(FormatStyle::LK_ObjC, Style->Language);
120
121  Style = getStyle("{}""a.h""none""enum Foo {};");
122  ASSERT_TRUE((bool)Style);
123  EXPECT_EQ(FormatStyle::LK_Cpp, Style->Language);
124
125  Style =
126      getStyle("{}""a.h""none""inline void Foo() { Log(@\"Foo\"); }\n");
127  ASSERT_TRUE((bool)Style);
128  EXPECT_EQ(FormatStyle::LK_ObjC, Style->Language);
129
130  Style =
131      getStyle("{}""a.h""none""inline void Foo() { Log(\"Foo\"); }\n");
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]; }\n");
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}; }\n");
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}; }\n");
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;\n");
152  ASSERT_TRUE((bool)Style);
153  EXPECT_EQ(FormatStyle::LK_ObjC, Style->Language);
154
155  Style = getStyle("{}""a.h""none""extern NSInteger Foo();\n");
156  ASSERT_TRUE((bool)Style);
157  EXPECT_EQ(FormatStyle::LK_ObjC, Style->Language);
158
159  Style = getStyle("{}""a.h""none""NSObject *Foo();\n");
160  ASSERT_TRUE((bool)Style);
161  EXPECT_EQ(FormatStyle::LK_ObjC, Style->Language);
162
163  Style = getStyle("{}""a.h""none""NSSet *Foo();\n");
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               "});\n");
195}
196
197TEST_F(FormatTestObjC, FormatObjCAutoreleasepool) {
198  verifyFormat("@autoreleasepool {\n"
199               "  f();\n"
200               "}\n"
201               "@autoreleasepool {\n"
202               "  f();\n"
203               "}\n");
204  Style.BreakBeforeBraces = FormatStyle::BS_Custom;
205  Style.BraceWrapping.AfterControlStatement = true;
206  verifyFormat("@autoreleasepool\n"
207               "{\n"
208               "  f();\n"
209               "}\n"
210               "@autoreleasepool\n"
211               "{\n"
212               "  f();\n"
213               "}\n");
214}
215
216TEST_F(FormatTestObjC, FormatObjCGenerics) {
217  Style.ColumnLimit = 40;
218  verifyFormat("int aaaaaaaaaaaaaaaa(\n"
219               "    NSArray<aaaaaaaaaaaaaaaaaa *>\n"
220               "        aaaaaaaaaaaaaaaaa);\n");
221  verifyFormat("int aaaaaaaaaaaaaaaa(\n"
222               "    NSArray<aaaaaaaaaaaaaaaaaaa<\n"
223               "        aaaaaaaaaaaaaaaa *> *>\n"
224               "        aaaaaaaaaaaaaaaaa);\n");
225}
226
227TEST_F(FormatTestObjC, FormatObjCSynchronized) {
228  verifyFormat("@synchronized(self) {\n"
229               "  f();\n"
230               "}\n"
231               "@synchronized(self) {\n"
232               "  f();\n"
233               "}\n");
234  Style.BreakBeforeBraces = FormatStyle::BS_Custom;
235  Style.BraceWrapping.AfterControlStatement = true;
236  verifyFormat("@synchronized(self)\n"
237               "{\n"
238               "  f();\n"
239               "}\n"
240               "@synchronized(self)\n"
241               "{\n"
242               "  f();\n"
243               "}\n");
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 (HackStuff) {\n"
328               "  int _i;\n"
329               "}\n"
330               "+ (id)init;\n"
331               "@end");
332
333  verifyFormat("@interface Foo () {\n"
334               "  int _i;\n"
335               "}\n"
336               "+ (id)init;\n"
337               "@end");
338
339  verifyFormat("@interface Foo (HackStuff) <MyProtocol> {\n"
340               "  int _i;\n"
341               "}\n"
342               "+ (id)init;\n"
343               "@end");
344  verifyFormat("@interface Foo\n"
345               "- (void)foo {\n"
346               "}\n"
347               "@end\n"
348               "@implementation Bar\n"
349               "- (void)bar {\n"
350               "}\n"
351               "@end");
352  Style.ColumnLimit = 40;
353  verifyFormat("@interface ccccccccccccc () <\n"
354               "    ccccccccccccc, ccccccccccccc,\n"
355               "    ccccccccccccc, ccccccccccccc> {\n"
356               "}");
357  verifyFormat("@interface ccccccccccccc (ccccccccccc) <\n"
358               "    ccccccccccccc> {\n"
359               "}");
360  Style.ObjCBinPackProtocolList = FormatStyle::BPS_Never;
361  verifyFormat("@interface ddddddddddddd () <\n"
362               "    ddddddddddddd,\n"
363               "    ddddddddddddd,\n"
364               "    ddddddddddddd,\n"
365               "    ddddddddddddd> {\n"
366               "}");
367
368  Style.BinPackParameters = false;
369  Style.ObjCBinPackProtocolList = FormatStyle::BPS_Auto;
370  verifyFormat("@interface eeeeeeeeeeeee () <\n"
371               "    eeeeeeeeeeeee,\n"
372               "    eeeeeeeeeeeee,\n"
373               "    eeeeeeeeeeeee,\n"
374               "    eeeeeeeeeeeee> {\n"
375               "}");
376  Style.ObjCBinPackProtocolList = FormatStyle::BPS_Always;
377  verifyFormat("@interface fffffffffffff () <\n"
378               "    fffffffffffff, fffffffffffff,\n"
379               "    fffffffffffff, fffffffffffff> {\n"
380               "}");
381
382  Style = getGoogleStyle(FormatStyle::LK_ObjC);
383  verifyFormat("@interface Foo : NSObject <NSSomeDelegate> {\n"
384               " @public\n"
385               "  int field1;\n"
386               " @protected\n"
387               "  int field2;\n"
388               " @private\n"
389               "  int field3;\n"
390               " @package\n"
391               "  int field4;\n"
392               "}\n"
393               "+ (id)init;\n"
394               "@end");
395  verifyFormat("@interface Foo : Bar <Baz, Quux>\n"
396               "+ (id)init;\n"
397               "@end");
398  verifyFormat("@interface Foo (HackStuff) <MyProtocol>\n"
399               "+ (id)init;\n"
400               "@end");
401  Style.ColumnLimit = 40;
402  // BinPackParameters should be true by default.
403  verifyFormat("void eeeeeeee(int eeeee, int eeeee,\n"
404               "              int eeeee, int eeeee);\n");
405  // ObjCBinPackProtocolList should be BPS_Never by default.
406  verifyFormat("@interface fffffffffffff () <\n"
407               "    fffffffffffff,\n"
408               "    fffffffffffff,\n"
409               "    fffffffffffff,\n"
410               "    fffffffffffff> {\n"
411               "}");
412}
413
414TEST_F(FormatTestObjC, FormatObjCImplementation) {
415  verifyFormat("@implementation Foo : NSObject {\n"
416               "@public\n"
417               "  int field1;\n"
418               "@protected\n"
419               "  int field2;\n"
420               "@private\n"
421               "  int field3;\n"
422               "@package\n"
423               "  int field4;\n"
424               "}\n"
425               "+ (id)init {\n}\n"
426               "@end");
427
428  verifyFormat("@implementation Foo\n"
429               "+ (id)init {\n"
430               "  if (true)\n"
431               "    return nil;\n"
432               "}\n"
433               "// Look, a comment!\n"
434               "- (int)answerWith:(int)i {\n"
435               "  return i;\n"
436               "}\n"
437               "+ (int)answerWith:(int)i {\n"
438               "  return i;\n"
439               "}\n"
440               "@end");
441
442  verifyFormat("@implementation Foo\n"
443               "@end\n"
444               "@implementation Bar\n"
445               "@end");
446
447  EXPECT_EQ("@implementation Foo : Bar\n"
448            "+ (id)init {\n}\n"
449            "- (void)foo {\n}\n"
450            "@end",
451            format("@implementation Foo : Bar\n"
452                   "+(id)init{}\n"
453                   "-(void)foo{}\n"
454                   "@end"));
455
456  verifyFormat("@implementation Foo {\n"
457               "  int _i;\n"
458               "}\n"
459               "+ (id)init {\n}\n"
460               "@end");
461
462  verifyFormat("@implementation Foo : Bar {\n"
463               "  int _i;\n"
464               "}\n"
465               "+ (id)init {\n}\n"
466               "@end");
467
468  verifyFormat("@implementation Foo (HackStuff)\n"
469               "+ (id)init {\n}\n"
470               "@end");
471  verifyFormat("@implementation ObjcClass\n"
472               "- (void)method;\n"
473               "{}\n"
474               "@end");
475
476  Style = getGoogleStyle(FormatStyle::LK_ObjC);
477  verifyFormat("@implementation Foo : NSObject {\n"
478               " @public\n"
479               "  int field1;\n"
480               " @protected\n"
481               "  int field2;\n"
482               " @private\n"
483               "  int field3;\n"
484               " @package\n"
485               "  int field4;\n"
486               "}\n"
487               "+ (id)init {\n}\n"
488               "@end");
489}
490
491TEST_F(FormatTestObjC, FormatObjCProtocol) {
492  verifyFormat("@protocol Foo\n"
493               "@property(weak) id delegate;\n"
494               "- (NSUInteger)numberOfThings;\n"
495               "@end");
496
497  verifyFormat("@protocol MyProtocol <NSObject>\n"
498               "- (NSUInteger)numberOfThings;\n"
499               "@end");
500
501  verifyFormat("@protocol Foo;\n"
502               "@protocol Bar;\n");
503
504  verifyFormat("@protocol Foo\n"
505               "@end\n"
506               "@protocol Bar\n"
507               "@end");
508
509  verifyFormat("FOUNDATION_EXPORT NS_AVAILABLE_IOS(10.0) @protocol Foo\n"
510               "@property(assign, readwrite) NSInteger bar;\n"
511               "@end");
512
513  verifyFormat("@protocol myProtocol\n"
514               "- (void)mandatoryWithInt:(int)i;\n"
515               "@optional\n"
516               "- (void)optional;\n"
517               "@required\n"
518               "- (void)required;\n"
519               "@optional\n"
520               "@property(assign) int madProp;\n"
521               "@end\n");
522
523  verifyFormat("@property(nonatomic, assign, readonly)\n"
524               "    int *looooooooooooooooooooooooooooongNumber;\n"
525               "@property(nonatomic, assign, readonly)\n"
526               "    NSString *looooooooooooooooooooooooooooongName;");
527
528  verifyFormat("@implementation PR18406\n"
529               "}\n"
530               "@end");
531
532  Style = getGoogleStyle(FormatStyle::LK_ObjC);
533  verifyFormat("@protocol MyProtocol <NSObject>\n"
534               "- (NSUInteger)numberOfThings;\n"
535               "@end");
536}
537
538TEST_F(FormatTestObjC, FormatObjCMethodDeclarations) {
539  verifyFormat("- (void)doSomethingWith:(GTMFoo *)theFoo\n"
540               "                   rect:(NSRect)theRect\n"
541               "               interval:(float)theInterval {\n"
542               "}");
543  verifyFormat("- (void)shortf:(GTMFoo *)theFoo\n"
544               "      longKeyword:(NSRect)theRect\n"
545               "    longerKeyword:(float)theInterval\n"
546               "            error:(NSError **)theError {\n"
547               "}");
548  verifyFormat("- (void)shortf:(GTMFoo *)theFoo\n"
549               "          longKeyword:(NSRect)theRect\n"
550               "    evenLongerKeyword:(float)theInterval\n"
551               "                error:(NSError **)theError {\n"
552               "}");
553  verifyFormat("+ (instancetype)new;\n");
554  Style.ColumnLimit = 60;
555  verifyFormat("- (instancetype)initXxxxxx:(id<x>)x\n"
556               "                         y:(id<yyyyyyyyyyyyyyyyyyyy>)y\n"
557               "    NS_DESIGNATED_INITIALIZER;");
558  verifyFormat("- (void)drawRectOn:(id)surface\n"
559               "            ofSize:(size_t)height\n"
560               "                  :(size_t)width;");
561  Style.ColumnLimit = 40;
562  // Make sure selectors with 0, 1, or more arguments are indented when wrapped.
563  verifyFormat("- (aaaaaaaaaaaaaaaaaaaaaaaaaaaaa)\n"
564               "    aaaaaaaaaaaaaaaaaaaaaaaaaaaa;\n");
565  verifyFormat("- (aaaaaaaaaaaaaaaaaaaaaaaaaaaaa)\n"
566               "    aaaaaaaaaaaaaaaaaaaaaaaaaaaa:(int)a;\n");
567  verifyFormat("- (aaaaaaaaaaaaaaaaaaaaaaaaaaaaa)\n"
568               "    aaaaaaaaaaaaaaaaaaaaaaaaaaaa:(int)a\n"
569               "    aaaaaaaaaaaaaaaaaaaaaaaaaaaa:(int)a;\n");
570  verifyFormat("- (aaaaaaaaaaaaaaaaaaaaaaaaaaaaa)\n"
571               "     aaaaaaaaaaaaaaaaaaaaaaaaaaa:(int)a\n"
572               "    aaaaaaaaaaaaaaaaaaaaaaaaaaaa:(int)a;\n");
573  verifyFormat("- (aaaaaaaaaaaaaaaaaaaaaaaaaaaaa)\n"
574               "    aaaaaaaaaaaaaaaaaaaaaaaaaaaa:(int)a\n"
575               "     aaaaaaaaaaaaaaaaaaaaaaaaaaa:(int)a;\n");
576
577  // Continuation indent width should win over aligning colons if the function
578  // name is long.
579  Style = getGoogleStyle(FormatStyle::LK_ObjC);
580  Style.ColumnLimit = 40;
581  verifyFormat("- (void)shortf:(GTMFoo *)theFoo\n"
582               "    dontAlignNamef:(NSRect)theRect {\n"
583               "}");
584
585  // Make sure we don't break aligning for short parameter names.
586  verifyFormat("- (void)shortf:(GTMFoo *)theFoo\n"
587               "       aShortf:(NSRect)theRect {\n"
588               "}");
589
590  // Format pairs correctly.
591  Style.ColumnLimit = 80;
592  verifyFormat("- (void)drawRectOn:(id)surface\n"
593               "            ofSize:(aaaaaaaa)height\n"
594               "                  :(size_t)width\n"
595               "          atOrigin:(size_t)x\n"
596               "                  :(size_t)y\n"
597               "             aaaaa:(a)yyy\n"
598               "               bbb:(d)cccc;");
599  verifyFormat("- (void)drawRectOn:(id)surface ofSize:(aaa)height:(bbb)width;");
600
601  // BraceWrapping AfterFunction is respected for ObjC methods 
602  Style = getGoogleStyle(FormatStyle::LK_ObjC);
603  Style.BreakBeforeBraces = FormatStyle::BS_Custom;
604  Style.BraceWrapping.AfterFunction = true;
605  verifyFormat("@implementation Foo\n"
606               "- (void)foo:(id)bar\n"
607               "{\n"
608               "}\n"
609               "@end\n");
610}
611
612TEST_F(FormatTestObjC, FormatObjCMethodExpr) {
613  verifyFormat("[foo bar:baz];");
614  verifyFormat("[foo bar]->baz;");
615  verifyFormat("return [foo bar:baz];");
616  verifyFormat("return (a)[foo bar:baz];");
617  verifyFormat("f([foo bar:baz]);");
618  verifyFormat("f(2, [foo bar:baz]);");
619  verifyFormat("f(2, a ? b : c);");
620  verifyFormat("[[self initWithInt:4] bar:[baz quux:arrrr]];");
621
622  // Unary operators.
623  verifyFormat("int a = +[foo bar:baz];");
624  verifyFormat("int a = -[foo bar:baz];");
625  verifyFormat("int a = ![foo bar:baz];");
626  verifyFormat("int a = ~[foo bar:baz];");
627  verifyFormat("int a = ++[foo bar:baz];");
628  verifyFormat("int a = --[foo bar:baz];");
629  verifyFormat("int a = sizeof [foo bar:baz];");
630  verifyFormat("int a = alignof [foo bar:baz];");
631  verifyFormat("int a = &[foo bar:baz];");
632  verifyFormat("int a = *[foo bar:baz];");
633  // FIXME: Make casts work, without breaking f()[4].
634  // verifyFormat("int a = (int)[foo bar:baz];");
635  // verifyFormat("return (int)[foo bar:baz];");
636  // verifyFormat("(void)[foo bar:baz];");
637  verifyFormat("return (MyType *)[self.tableView cellForRowAtIndexPath:cell];");
638
639  // Binary operators.
640  verifyFormat("[foo bar:baz], [foo bar:baz];");
641  verifyFormat("[foo bar:baz] = [foo bar:baz];");
642  verifyFormat("[foo bar:baz] *= [foo bar:baz];");
643  verifyFormat("[foo bar:baz] /= [foo bar:baz];");
644  verifyFormat("[foo bar:baz] %= [foo bar:baz];");
645  verifyFormat("[foo bar:baz] += [foo bar:baz];");
646  verifyFormat("[foo bar:baz] -= [foo bar:baz];");
647  verifyFormat("[foo bar:baz] <<= [foo bar:baz];");
648  verifyFormat("[foo bar:baz] >>= [foo bar:baz];");
649  verifyFormat("[foo bar:baz] &= [foo bar:baz];");
650  verifyFormat("[foo bar:baz] ^= [foo bar:baz];");
651  verifyFormat("[foo bar:baz] |= [foo bar:baz];");
652  verifyFormat("[foo bar:baz] ? [foo bar:baz] : [foo bar:baz];");
653  verifyFormat("[foo bar:baz] || [foo bar:baz];");
654  verifyFormat("[foo bar:baz] && [foo bar:baz];");
655  verifyFormat("[foo bar:baz] | [foo bar:baz];");
656  verifyFormat("[foo bar:baz] ^ [foo bar:baz];");
657  verifyFormat("[foo bar:baz] & [foo bar:baz];");
658  verifyFormat("[foo bar:baz] == [foo bar:baz];");
659  verifyFormat("[foo bar:baz] != [foo bar:baz];");
660  verifyFormat("[foo bar:baz] >= [foo bar:baz];");
661  verifyFormat("[foo bar:baz] <= [foo bar:baz];");
662  verifyFormat("[foo bar:baz] > [foo bar:baz];");
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  // Whew!
672
673  verifyFormat("return in[42];");
674  verifyFormat("for (auto v : in[1]) {\n}");
675  verifyFormat("for (int i = 0; i < in[a]; ++i) {\n}");
676  verifyFormat("for (int i = 0; in[a] < i; ++i) {\n}");
677  verifyFormat("for (int i = 0; i < n; ++i, ++in[a]) {\n}");
678  verifyFormat("for (int i = 0; i < n; ++i, in[a]++) {\n}");
679  verifyFormat("for (int i = 0; i < f(in[a]); ++i, in[a]++) {\n}");
680  verifyFormat("for (id foo in [self getStuffFor:bla]) {\n"
681               "}");
682  verifyFormat("[self aaaaa:MACRO(a, b:, c:)];");
683  verifyFormat("[self aaaaa:MACRO(a, b:c:, d:e:)];");
684  verifyFormat("[self aaaaa:MACRO(a, b:c:d:, e:f:g:)];");
685  verifyFormat("int XYMyFoo(int a, int b) NS_SWIFT_NAME(foo(self:scale:));");
686  verifyFormat("[self aaaaa:(1 + 2) bbbbb:3];");
687  verifyFormat("[self aaaaa:(Type)a bbbbb:3];");
688
689  verifyFormat("[self stuffWithInt:(4 + 2) float:4.5];");
690  verifyFormat("[self stuffWithInt:a ? b : c float:4.5];");
691  verifyFormat("[self stuffWithInt:a ? [self foo:bar] : c];");
692  verifyFormat("[self stuffWithInt:a ? (e ? f : g) : c];");
693  verifyFormat("[cond ? obj1 : obj2 methodWithParam:param]");
694  verifyFormat("[button setAction:@selector(zoomOut:)];");
695  verifyFormat("[color getRed:&r green:&g blue:&b alpha:&a];");
696
697  verifyFormat("arr[[self indexForFoo:a]];");
698  verifyFormat("throw [self errorFor:a];");
699  verifyFormat("@throw [self errorFor:a];");
700
701  verifyFormat("[(id)foo bar:(id)baz quux:(id)snorf];");
702  verifyFormat("[(id)foo bar:(id) ? baz : quux];");
703  verifyFormat("4 > 4 ? (id)a : (id)baz;");
704
705  unsigned PreviousColumnLimit = Style.ColumnLimit;
706  Style.ColumnLimit = 50;
707  // Instead of:
708  // bool a =
709  //     ([object a:42] == 0 || [object a:42
710  //                                    b:42] == 0);
711  verifyFormat("bool a = ([object a:42] == 0 ||\n"
712               "          [object a:42 b:42] == 0);");
713  Style.ColumnLimit = PreviousColumnLimit;
714  verifyFormat("bool a = ([aaaaaaaa aaaaa] == aaaaaaaaaaaaaaaaa ||\n"
715               "          [aaaaaaaa aaaaa] == aaaaaaaaaaaaaaaaaaaa);");
716
717  // This tests that the formatter doesn't break after "backing" but before ":",
718  // which would be at 80 columns.
719  verifyFormat(
720      "void f() {\n"
721      "  if ((self = [super initWithContentRect:contentRect\n"
722      "                               styleMask:styleMask ?: otherMask\n"
723      "                                 backing:NSBackingStoreBuffered\n"
724      "                                   defer:YES]))");
725
726  verifyFormat(
727      "[foo checkThatBreakingAfterColonWorksOk:\n"
728      "         [bar ifItDoes:reduceOverallLineLengthLikeInThisCase]];");
729
730  verifyFormat("[myObj short:arg1 // Force line break\n"
731               "          longKeyword:arg2 != nil ? arg2 : @\"longKeyword\"\n"
732               "    evenLongerKeyword:arg3 ?: @\"evenLongerKeyword\"\n"
733               "                error:arg4];");
734  verifyFormat(
735      "void f() {\n"
736      "  popup_window_.reset([[RenderWidgetPopupWindow alloc]\n"
737      "      initWithContentRect:NSMakeRect(origin_global.x, origin_global.y,\n"
738      "                                     pos.width(), pos.height())\n"
739      "                styleMask:NSBorderlessWindowMask\n"
740      "                  backing:NSBackingStoreBuffered\n"
741      "                    defer:NO]);\n"
742      "}");
743  verifyFormat("[contentsContainer replaceSubview:[subviews objectAtIndex:0]\n"
744               "                             with:contentsNativeView];");
745
746  verifyFormat(
747      "[pboard addTypes:[NSArray arrayWithObject:kBookmarkButtonDragType]\n"
748      "           owner:nillllll];");
749
750  verifyFormat(
751      "[pboard setData:[NSData dataWithBytes:&button length:sizeof(button)]\n"
752      "        forType:kBookmarkButtonDragType];");
753
754  verifyFormat("[defaultCenter addObserver:self\n"
755               "                  selector:@selector(willEnterFullscreen)\n"
756               "                      name:kWillEnterFullscreenNotification\n"
757               "                    object:nil];");
758  verifyFormat("[image_rep drawInRect:drawRect\n"
759               "             fromRect:NSZeroRect\n"
760               "            operation:NSCompositeCopy\n"
761               "             fraction:1.0\n"
762               "       respectFlipped:NO\n"
763               "                hints:nil];");
764  verifyFormat("[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
765               "    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa];");
766  verifyFormat("[aaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaa)\n"
767               "    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa];");
768  verifyFormat("[aaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaa[aaaaaaaaaaaaaaaaaaaaa]\n"
769               "    aaaaaaaaaaaaaaaaaaaaaa];");
770
771  verifyFormat(
772      "scoped_nsobject<NSTextField> message(\n"
773      "    // The frame will be fixed up when |-setMessageText:| is called.\n"
774      "    [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 0, 0)]);");
775  verifyFormat("[self aaaaaa:bbbbbbbbbbbbb\n"
776               "    aaaaaaaaaa:bbbbbbbbbbbbbbbbb\n"
777               "         aaaaa:bbbbbbbbbbb + bbbbbbbbbbbb\n"
778               "          aaaa:bbb];");
779  verifyFormat("[self param:function( //\n"
780               "                parameter)]");
781  verifyFormat(
782      "[self aaaaaaaaaa:aaaaaaaaaaaaaaa | aaaaaaaaaaaaaaa | aaaaaaaaaaaaaaa |\n"
783      "                 aaaaaaaaaaaaaaa | aaaaaaaaaaaaaaa | aaaaaaaaaaaaaaa |\n"
784      "                 aaaaaaaaaaaaaaa | aaaaaaaaaaaaaaa];");
785
786  // Variadic parameters.
787  verifyFormat(
788      "NSArray *myStrings = [NSArray stringarray:@\"a\", @\"b\", nil];");
789  verifyFormat(
790      "[self aaaaaaaaaaaaa:aaaaaaaaaaaaaaa, aaaaaaaaaaaaaaa, aaaaaaaaaaaaaaa,\n"
791      "                    aaaaaaaaaaaaaaa, aaaaaaaaaaaaaaa, aaaaaaaaaaaaaaa,\n"
792      "                    aaaaaaaaaaaaaaa, aaaaaaaaaaaaaaa];");
793
794  verifyFormat("[self // break\n"
795               "      a:a\n"
796               "    aaa:aaa];");
797
798  // Formats pair-parameters.
799  verifyFormat("[I drawRectOn:surface ofSize:aa:bbb atOrigin:cc:dd];");
800  verifyFormat("[I drawRectOn:surface //\n"
801               "       ofSize:aa:bbb\n"
802               "     atOrigin:cc:dd];");
803
804  // Inline block as a first argument.
805  verifyFormat("[object justBlock:^{\n"
806               "  a = 42;\n"
807               "}];");
808  verifyFormat("[object\n"
809               "    justBlock:^{\n"
810               "      a = 42;\n"
811               "    }\n"
812               "     notBlock:42\n"
813               "            a:42];");
814  verifyFormat("[object\n"
815               "    firstBlock:^{\n"
816               "      a = 42;\n"
817               "    }\n"
818               "    blockWithLongerName:^{\n"
819               "      a = 42;\n"
820               "    }];");
821  verifyFormat("[object\n"
822               "    blockWithLongerName:^{\n"
823               "      a = 42;\n"
824               "    }\n"
825               "    secondBlock:^{\n"
826               "      a = 42;\n"
827               "    }];");
828  verifyFormat("[object\n"
829               "    firstBlock:^{\n"
830               "      a = 42;\n"
831               "    }\n"
832               "    notBlock:42\n"
833               "    secondBlock:^{\n"
834               "      a = 42;\n"
835               "    }];");
836
837  // Space between cast rparen and selector name component.
838  verifyFormat("[((Foo *)foo) bar];");
839  verifyFormat("[((Foo *)foo) bar:1 blech:2];");
840
841  Style.ColumnLimit = 20;
842  verifyFormat("aaaaa = [a aa:aa\n"
843               "           aa:aa];");
844  verifyFormat("aaaaaa = [aa aa:aa\n"
845               "             aa:aa];");
846
847  // Message receiver taking multiple lines.
848  // Non-corner case.
849  verifyFormat("[[object block:^{\n"
850               "  return 42;\n"
851               "}] a:42 b:42];");
852  // Arguments just fit into one line.
853  verifyFormat("[[object block:^{\n"
854               "  return 42;\n"
855               "}] aaaaaaa:42 b:42];");
856  // Arguments just over a column limit.
857  verifyFormat("[[object block:^{\n"
858               "  return 42;\n"
859               "}] aaaaaaa:42\n"
860               "        bb:42];");
861  // Arguments just fit into one line.
862  Style.ColumnLimit = 23;
863  verifyFormat("[[obj a:42\n"
864               "      b:42\n"
865               "      c:42\n"
866               "      d:42] e:42 f:42];");
867
868  // Arguments do not fit into one line with a receiver.
869  Style.ColumnLimit = 20;
870  verifyFormat("[[obj a:42] a:42\n"
871               "            b:42];");
872  verifyFormat("[[obj a:42] a:42\n"
873               "            b:42\n"
874               "            c:42];");
875  verifyFormat("[[obj aaaaaa:42\n"
876               "           b:42]\n"
877               "    cc:42\n"
878               "     d:42];");
879
880  // Avoid breaking receiver expression.
881  Style.ColumnLimit = 30;
882  verifyFormat("fooooooo =\n"
883               "    [[obj fooo] aaa:42\n"
884               "                aaa:42];");
885  verifyFormat("[[[obj foo] bar] aa:42\n"
886               "                 bb:42\n"
887               "                 cc:42];");
888
889  Style.ColumnLimit = 70;
890  verifyFormat(
891      "void f() {\n"
892      "  popup_wdow_.reset([[RenderWidgetPopupWindow alloc]\n"
893      "      iniithContentRect:NSMakRet(origin_global.x, origin_global.y,\n"
894      "                                 pos.width(), pos.height())\n"
895      "                syeMask:NSBorderlessWindowMask\n"
896      "                  bking:NSBackingStoreBuffered\n"
897      "                    der:NO]);\n"
898      "}");
899
900  Style.ColumnLimit = 60;
901  verifyFormat("[call aaaaaaaa.aaaaaa.aaaaaaaa.aaaaaaaa.aaaaaaaa.aaaaaaaa\n"
902               "        .aaaaaaaa];"); // FIXME: Indentation seems off.
903  // FIXME: This violates the column limit.
904  verifyFormat(
905      "[aaaaaaaaaaaaaaaaaaaaaaaaa\n"
906      "    aaaaaaaaaaaaaaaaa:aaaaaaaa\n"
907      "                  aaa:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa];");
908
909  Style = getChromiumStyle(FormatStyle::LK_ObjC);
910  Style.ColumnLimit = 80;
911  verifyFormat(
912      "void f() {\n"
913      "  popup_window_.reset([[RenderWidgetPopupWindow alloc]\n"
914      "      initWithContentRect:NSMakeRect(origin_global.x, origin_global.y,\n"
915      "                                     pos.width(), pos.height())\n"
916      "                styleMask:NSBorderlessWindowMask\n"
917      "                  backing:NSBackingStoreBuffered\n"
918      "                    defer:NO]);\n"
919      "}");
920
921  // Respect continuation indent and colon alignment (e.g. when object name is
922  // short, and first selector is the longest one)
923  Style = getLLVMStyle();
924  Style.Language = FormatStyle::LK_ObjC;
925  Style.ContinuationIndentWidth = 8;
926  verifyFormat("[self performSelectorOnMainThread:@selector(loadAccessories)\n"
927               "                       withObject:nil\n"
928               "                    waitUntilDone:false];");
929  verifyFormat("[self performSelector:@selector(loadAccessories)\n"
930               "        withObjectOnMainThread:nil\n"
931               "                 waitUntilDone:false];");
932  verifyFormat("[aaaaaaaaaaaaaaaaaaaaaaaaa\n"
933               "        performSelectorOnMainThread:@selector(loadAccessories)\n"
934               "                         withObject:nil\n"
935               "                      waitUntilDone:false];");
936  verifyFormat("[self // force wrapping\n"
937               "        performSelectorOnMainThread:@selector(loadAccessories)\n"
938               "                         withObject:nil\n"
939               "                      waitUntilDone:false];");
940}
941
942TEST_F(FormatTestObjC, ObjCAt) {
943  verifyFormat("@autoreleasepool");
944  verifyFormat("@catch");
945  verifyFormat("@class");
946  verifyFormat("@compatibility_alias");
947  verifyFormat("@defs");
948  verifyFormat("@dynamic");
949  verifyFormat("@encode");
950  verifyFormat("@end");
951  verifyFormat("@finally");
952  verifyFormat("@implementation");
953  verifyFormat("@import");
954  verifyFormat("@interface");
955  verifyFormat("@optional");
956  verifyFormat("@package");
957  verifyFormat("@private");
958  verifyFormat("@property");
959  verifyFormat("@protected");
960  verifyFormat("@protocol");
961  verifyFormat("@public");
962  verifyFormat("@required");
963  verifyFormat("@selector");
964  verifyFormat("@synchronized");
965  verifyFormat("@synthesize");
966  verifyFormat("@throw");
967  verifyFormat("@try");
968
969  EXPECT_EQ("@interface", format("@ interface"));
970
971  // The precise formatting of this doesn't matter, nobody writes code like
972  // this.
973  verifyFormat("@ /*foo*/ interface");
974}
975
976TEST_F(FormatTestObjC, ObjCBlockTypesAndVariables) {
977  verifyFormat("void DoStuffWithBlockType(int (^)(char));");
978  verifyFormat("int (^foo)(char, float);");
979  verifyFormat("int (^foo[10])(char, float);");
980  verifyFormat("int (^foo[kNumEntries])(char, float);");
981  verifyFormat("int (^foo[kNumEntries + 10])(char, float);");
982  verifyFormat("int (^foo[(kNumEntries + 10)])(char, float);");
983}
984
985TEST_F(FormatTestObjC, ObjCSnippets) {
986  verifyFormat("@autoreleasepool {\n"
987               "  foo();\n"
988               "}");
989  verifyFormat("@class Foo, Bar;");
990  verifyFormat("@compatibility_alias AliasName ExistingClass;");
991  verifyFormat("@dynamic textColor;");
992  verifyFormat("char *buf1 = @encode(int *);");
993  verifyFormat("char *buf1 = @encode(typeof(4 * 5));");
994  verifyFormat("char *buf1 = @encode(int **);");
995  verifyFormat("Protocol *proto = @protocol(p1);");
996  verifyFormat("SEL s = @selector(foo:);");
997  verifyFormat("@synchronized(self) {\n"
998               "  f();\n"
999               "}");
1000
1001  verifyFormat("@import foo.bar;\n"
1002               "@import baz;");
1003
1004  verifyFormat("@synthesize dropArrowPosition = dropArrowPosition_;");
1005
1006  verifyFormat("@property(assign, nonatomic) CGFloat hoverAlpha;");
1007  verifyFormat("@property(assign, getter=isEditable) BOOL editable;");
1008
1009  Style.ColumnLimit = 50;
1010  verifyFormat("@interface Foo\n"
1011               "- (void)doStuffWithFoo:(id)name\n"
1012               "                   bar:(id)bar\n"
1013               "                   baz:(id)baz\n"
1014               "    NS_SWIFT_NAME(doStuff(withFoo:bar:baz:));\n"
1015               "@end");
1016
1017  Style = getMozillaStyle();
1018  verifyFormat("@property (assign, getter=isEditable) BOOL editable;");
1019  verifyFormat("@property BOOL editable;");
1020
1021  Style = getWebKitStyle();
1022  verifyFormat("@property (assign, getter=isEditable) BOOL editable;");
1023  verifyFormat("@property BOOL editable;");
1024
1025  Style = getGoogleStyle(FormatStyle::LK_ObjC);
1026  verifyFormat("@synthesize dropArrowPosition = dropArrowPosition_;");
1027  verifyFormat("@property(assign, getter=isEditable) BOOL editable;");
1028}
1029
1030TEST_F(FormatTestObjC, ObjCForIn) {
1031  verifyFormat("- (void)test {\n"
1032               "  for (NSString *n in arrayOfStrings) {\n"
1033               "    foo(n);\n"
1034               "  }\n"
1035               "}");
1036  verifyFormat("- (void)test {\n"
1037               "  for (NSString *n in (__bridge NSArray *)arrayOfStrings) {\n"
1038               "    foo(n);\n"
1039               "  }\n"
1040               "}");
1041  verifyFormat("for (Foo *x in bar) {\n}");
1042  verifyFormat("for (Foo *x in [bar baz]) {\n}");
1043  verifyFormat("for (Foo *x in [bar baz:blech]) {\n}");
1044  verifyFormat("for (Foo *x in [bar baz:blech, 1, 2, 3, 0]) {\n}");
1045  verifyFormat("for (Foo *x in [bar baz:^{\n"
1046               "       [uh oh];\n"
1047               "     }]) {\n}");
1048}
1049
1050TEST_F(FormatTestObjC, ObjCCxxKeywords) {
1051  verifyFormat("+ (instancetype)new {\n"
1052               "  return nil;\n"
1053               "}\n");
1054  verifyFormat("+ (instancetype)myNew {\n"
1055               "  return [self new];\n"
1056               "}\n");
1057  verifyFormat("SEL NewSelector(void) { return @selector(new); }\n");
1058  verifyFormat("SEL MacroSelector(void) { return MACRO(new); }\n");
1059  verifyFormat("+ (instancetype)delete {\n"
1060               "  return nil;\n"
1061               "}\n");
1062  verifyFormat("+ (instancetype)myDelete {\n"
1063               "  return [self delete];\n"
1064               "}\n");
1065  verifyFormat("SEL DeleteSelector(void) { return @selector(delete); }\n");
1066  verifyFormat("SEL MacroSelector(void) { return MACRO(delete); }\n");
1067  verifyFormat("MACRO(new:)\n");
1068  verifyFormat("MACRO(delete:)\n");
1069  verifyFormat("foo = @{MACRO(new:) : MACRO(delete:)}\n");
1070  verifyFormat("@implementation Foo\n"
1071               "// Testing\n"
1072               "- (Class)class {\n"
1073               "}\n"
1074               "- (void)foo {\n"
1075               "}\n"
1076               "@end\n");
1077  verifyFormat("@implementation Foo\n"
1078               "- (Class)class {\n"
1079               "}\n"
1080               "- (void)foo {\n"
1081               "}\n"
1082               "@end");
1083  verifyFormat("@implementation Foo\n"
1084               "+ (Class)class {\n"
1085               "}\n"
1086               "- (void)foo {\n"
1087               "}\n"
1088               "@end");
1089  verifyFormat("@implementation Foo\n"
1090               "- (Class)class:(Class)klass {\n"
1091               "}\n"
1092               "- (void)foo {\n"
1093               "}\n"
1094               "@end");
1095  verifyFormat("@implementation Foo\n"
1096               "+ (Class)class:(Class)klass {\n"
1097               "}\n"
1098               "- (void)foo {\n"
1099               "}\n"
1100               "@end");
1101
1102  verifyFormat("@interface Foo\n"
1103               "// Testing\n"
1104               "- (Class)class;\n"
1105               "- (void)foo;\n"
1106               "@end\n");
1107  verifyFormat("@interface Foo\n"
1108               "- (Class)class;\n"
1109               "- (void)foo;\n"
1110               "@end");
1111  verifyFormat("@interface Foo\n"
1112               "+ (Class)class;\n"
1113               "- (void)foo;\n"
1114               "@end");
1115  verifyFormat("@interface Foo\n"
1116               "- (Class)class:(Class)klass;\n"
1117               "- (void)foo;\n"
1118               "@end");
1119  verifyFormat("@interface Foo\n"
1120               "+ (Class)class:(Class)klass;\n"
1121               "- (void)foo;\n"
1122               "@end");
1123}
1124
1125TEST_F(FormatTestObjC, ObjCLiterals) {
1126  verifyFormat("@\"String\"");
1127  verifyFormat("@1");
1128  verifyFormat("@+4.8");
1129  verifyFormat("@-4");
1130  verifyFormat("@1LL");
1131  verifyFormat("@.5");
1132  verifyFormat("@'c'");
1133  verifyFormat("@true");
1134
1135  verifyFormat("NSNumber *smallestInt = @(-INT_MAX - 1);");
1136  verifyFormat("NSNumber *piOverTwo = @(M_PI / 2);");
1137  verifyFormat("NSNumber *favoriteColor = @(Green);");
1138  verifyFormat("NSString *path = @(getenv(\"PATH\"));");
1139
1140  verifyFormat("[dictionary setObject:@(1) forKey:@\"number\"];");
1141}
1142
1143TEST_F(FormatTestObjC, ObjCDictLiterals) {
1144  verifyFormat("@{");
1145  verifyFormat("@{}");
1146  verifyFormat("@{@\"one\" : @1}");
1147  verifyFormat("return @{@\"one\" : @1;");
1148  verifyFormat("@{@\"one\" : @1}");
1149
1150  verifyFormat("@{@\"one\" : @{@2 : @1}}");
1151  verifyFormat("@{\n"
1152               "  @\"one\" : @{@2 : @1},\n"
1153               "}");
1154
1155  verifyFormat("@{1 > 2 ? @\"one\" : @\"two\" : 1 > 2 ? @1 : @2}");
1156  verifyIncompleteFormat("[self setDict:@{}");
1157  verifyIncompleteFormat("[self setDict:@{@1 : @2}");
1158  verifyFormat("NSLog(@\"%@\", @{@1 : @2, @2 : @3}[@1]);");
1159  verifyFormat(
1160      "NSDictionary *masses = @{@\"H\" : @1.0078, @\"He\" : @4.0026};");
1161  verifyFormat(
1162      "NSDictionary *settings = @{AVEncoderKey : @(AVAudioQualityMax)};");
1163
1164  verifyFormat("NSDictionary *d = @{\n"
1165               "  @\"nam\" : NSUserNam(),\n"
1166               "  @\"dte\" : [NSDate date],\n"
1167               "  @\"processInfo\" : [NSProcessInfo processInfo]\n"
1168               "};");
1169  verifyFormat(
1170      "@{\n"
1171      "  NSFontAttributeNameeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee : "
1172      "regularFont,\n"
1173      "};");
1174  verifyFormat(
1175      "@{\n"
1176      "  NSFontAttributeNameeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee :\n"
1177      "      reeeeeeeeeeeeeeeeeeeeeeeegularFont,\n"
1178      "};");
1179
1180  // We should try to be robust in case someone forgets the "@".
1181  verifyFormat("NSDictionary *d = {\n"
1182               "  @\"nam\" : NSUserNam(),\n"
1183               "  @\"dte\" : [NSDate date],\n"
1184               "  @\"processInfo\" : [NSProcessInfo processInfo]\n"
1185               "};");
1186  verifyFormat("NSMutableDictionary *dictionary =\n"
1187               "    [NSMutableDictionary dictionaryWithDictionary:@{\n"
1188               "      aaaaaaaaaaaaaaaaaaaaa : aaaaaaaaaaaaa,\n"
1189               "      bbbbbbbbbbbbbbbbbb : bbbbb,\n"
1190               "      cccccccccccccccc : ccccccccccccccc\n"
1191               "    }];");
1192
1193  // Ensure that casts before the key are kept on the same line as the key.
1194  verifyFormat(
1195      "NSDictionary *d = @{\n"
1196      "  (aaaaaaaa id)aaaaaaaaa : (aaaaaaaa id)aaaaaaaaaaaaaaaaaaaaaaaa,\n"
1197      "  (aaaaaaaa id)aaaaaaaaaaaaaa : (aaaaaaaa id)aaaaaaaaaaaaaa,\n"
1198      "};");
1199  Style.ColumnLimit = 40;
1200  verifyFormat("int Foo() {\n"
1201               "  a12345 = @{a12345 : a12345};\n"
1202               "}");
1203  verifyFormat("int Foo() {\n"
1204               "  a12345 = @{a12345 : @(a12345)};\n"
1205               "}");
1206  verifyFormat("int Foo() {\n"
1207               "  a12345 = @{(Foo *)a12345 : @(a12345)};\n"
1208               "}");
1209  verifyFormat("int Foo() {\n"
1210               "  a12345 = @{@(a12345) : a12345};\n"
1211               "}");
1212  verifyFormat("int Foo() {\n"
1213               "  a12345 = @{@(a12345) : @YES};\n"
1214               "}");
1215  Style.SpacesInContainerLiterals = false;
1216  verifyFormat("int Foo() {\n"
1217               "  b12345 = @{b12345: b12345};\n"
1218               "}");
1219  verifyFormat("int Foo() {\n"
1220               "  b12345 = @{(Foo *)b12345: @(b12345)};\n"
1221               "}");
1222  Style.SpacesInContainerLiterals = true;
1223
1224  Style = getGoogleStyle(FormatStyle::LK_ObjC);
1225  verifyFormat(
1226      "@{\n"
1227      "  NSFontAttributeNameeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee : "
1228      "regularFont,\n"
1229      "};");
1230}
1231
1232TEST_F(FormatTestObjC, ObjCArrayLiterals) {
1233  verifyIncompleteFormat("@[");
1234  verifyFormat("@[]");
1235  verifyFormat(
1236      "NSArray *array = @[ @\" Hey \", NSApp, [NSNumber numberWithInt:42] ];");
1237  verifyFormat("return @[ @3, @[], @[ @4, @5 ] ];");
1238  verifyFormat("NSArray *array = @[ [foo description] ];");
1239
1240  verifyFormat(
1241      "NSArray *some_variable = @[\n"
1242      "  aaaa == bbbbbbbbbbb ? @\"aaaaaaaaaaaa\" : @\"aaaaaaaaaaaaaa\",\n"
1243      "  @\"aaaaaaaaaaaaaaaaa\",\n"
1244      "  @\"aaaaaaaaaaaaaaaaa\",\n"
1245      "  @\"aaaaaaaaaaaaaaaaa\",\n"
1246      "];");
1247  verifyFormat(
1248      "NSArray *some_variable = @[\n"
1249      "  aaaa == bbbbbbbbbbb ? @\"aaaaaaaaaaaa\" : @\"aaaaaaaaaaaaaa\",\n"
1250      "  @\"aaaaaaaaaaaaaaaa\", @\"aaaaaaaaaaaaaaaa\", @\"aaaaaaaaaaaaaaaa\"\n"
1251      "];");
1252  verifyFormat("NSArray *some_variable = @[\n"
1253               "  @\"aaaaaaaaaaaaaaaaa\",\n"
1254               "  @\"aaaaaaaaaaaaaaaaa\",\n"
1255               "  @\"aaaaaaaaaaaaaaaaa\",\n"
1256               "  @\"aaaaaaaaaaaaaaaaa\",\n"
1257               "];");
1258  verifyFormat("NSArray *array = @[\n"
1259               "  @\"a\",\n"
1260               "  @\"a\",\n" // Trailing comma -> one per line.
1261               "];");
1262
1263  // We should try to be robust in case someone forgets the "@".
1264  verifyFormat("NSArray *some_variable = [\n"
1265               "  @\"aaaaaaaaaaaaaaaaa\",\n"
1266               "  @\"aaaaaaaaaaaaaaaaa\",\n"
1267               "  @\"aaaaaaaaaaaaaaaaa\",\n"
1268               "  @\"aaaaaaaaaaaaaaaaa\",\n"
1269               "];");
1270  verifyFormat(
1271      "- (NSAttributedString *)attributedStringForSegment:(NSUInteger)segment\n"
1272      "                                             index:(NSUInteger)index\n"
1273      "                                nonDigitAttributes:\n"
1274      "                                    (NSDictionary *)noDigitAttributes;");
1275  verifyFormat("[someFunction someLooooooooooooongParameter:@[\n"
1276               "  NSBundle.mainBundle.infoDictionary[@\"a\"]\n"
1277               "]];");
1278  Style.ColumnLimit = 40;
1279  verifyFormat("int Foo() {\n"
1280               "  a12345 = @[ a12345, a12345 ];\n"
1281               "}");
1282  verifyFormat("int Foo() {\n"
1283               "  a123 = @[ (Foo *)a12345, @(a12345) ];\n"
1284               "}");
1285  Style.SpacesInContainerLiterals = false;
1286  verifyFormat("int Foo() {\n"
1287               "  b12345 = @[b12345, b12345];\n"
1288               "}");
1289  verifyFormat("int Foo() {\n"
1290               "  b12345 = @[(Foo *)b12345, @(b12345)];\n"
1291               "}");
1292  Style.SpacesInContainerLiterals = true;
1293  Style.ColumnLimit = 20;
1294  // We can't break string literals inside NSArray literals
1295  // (that raises -Wobjc-string-concatenation).
1296  verifyFormat("NSArray *foo = @[\n"
1297               "  @\"aaaaaaaaaaaaaaaaaaaaaaaaaa\"\n"
1298               "];\n");
1299}
1300
1301TEST_F(FormatTestObjC, BreaksCallStatementWhereSemiJustOverTheLimit) {
1302  Style.ColumnLimit = 60;
1303  // If the statement starting with 'a = ...' is put on a single line, the ';'
1304  // is at line 61.
1305  verifyFormat("int f(int a) {\n"
1306               "  a = [self aaaaaaaaaa:bbbbbbbbb\n"
1307               "             ccccccccc:dddddddd\n"
1308               "                    ee:fddd];\n"
1309               "}");
1310}
1311
1312TEST_F(FormatTestObjC, AlwaysBreakBeforeMultilineStrings) {
1313  Style = getGoogleStyle(FormatStyle::LK_ObjC);
1314  Style.ColumnLimit = 40;
1315  verifyFormat("aaaa = @\"bbbb\"\n"
1316               "       @\"cccc\";");
1317  verifyFormat("aaaa(@\"bbbb\"\n"
1318               "     @\"cccc\");");
1319  verifyFormat("aaaa(qqq, @\"bbbb\"\n"
1320               "          @\"cccc\");");
1321  verifyFormat("[aaaa qqqq:@\"bbbb\"\n"
1322               "           @\"cccc\"];");
1323  verifyFormat("aaaa = [aaaa qqqq:@\"bbbb\"\n"
1324               "                  @\"cccc\"];");
1325  verifyFormat("[aaaa qqqq:@\"bbbb\"\n"
1326               "           @\"cccc\"\n"
1327               "        rr:42\n"
1328               "    ssssss:@\"ee\"\n"
1329               "           @\"fffff\"];");
1330}
1331
1332TEST_F(FormatTestObjC, DisambiguatesCallsFromCppLambdas) {
1333  verifyFormat("x = ([a foo:bar] && b->c == 'd');");
1334  verifyFormat("x = ([a foo:bar] + b->c == 'd');");
1335  verifyFormat("x = ([a foo:bar] + !b->c == 'd');");
1336  verifyFormat("x = ([a foo:bar] + ~b->c == 'd');");
1337  verifyFormat("x = ([a foo:bar] - b->c == 'd');");
1338  verifyFormat("x = ([a foo:bar] / b->c == 'd');");
1339  verifyFormat("x = ([a foo:bar] % b->c == 'd');");
1340  verifyFormat("x = ([a foo:bar] | b->c == 'd');");
1341  verifyFormat("x = ([a foo:bar] || b->c == 'd');");
1342  verifyFormat("x = ([a foo:bar] && b->c == 'd');");
1343  verifyFormat("x = ([a foo:bar] == b->c == 'd');");
1344  verifyFormat("x = ([a foo:bar] != b->c == 'd');");
1345  verifyFormat("x = ([a foo:bar] <= b->c == 'd');");
1346  verifyFormat("x = ([a foo:bar] >= b->c == 'd');");
1347  verifyFormat("x = ([a foo:bar] << b->c == 'd');");
1348  verifyFormat("x = ([a foo:bar] ? b->c == 'd' : 'e');");
1349  // FIXME: The following are wrongly classified as C++ lambda expressions.
1350  // For example this code:
1351  //   x = ([a foo:bar] & b->c == 'd');
1352  // is formatted as:
1353  //   x = ([a foo:bar] & b -> c == 'd');
1354  // verifyFormat("x = ([a foo:bar] & b->c == 'd');");
1355  // verifyFormat("x = ([a foo:bar] > b->c == 'd');");
1356  // verifyFormat("x = ([a foo:bar] < b->c == 'd');");
1357  // verifyFormat("x = ([a foo:bar] >> b->c == 'd');");
1358}
1359
1360TEST_F(FormatTestObjC,  DisambiguatesCallsFromStructuredBindings) {
1361  verifyFormat("int f() {\n"
1362               "  if (a && [f arg])\n"
1363               "    return 0;\n"
1364               "}");
1365  verifyFormat("int f() {\n"
1366               "  if (a & [f arg])\n"
1367               "    return 0;\n"
1368               "}");
1369  verifyFormat("int f() {\n"
1370               "  for (auto &[elem] : list)\n"
1371               "    return 0;\n"
1372               "}");
1373  verifyFormat("int f() {\n"
1374               "  for (auto &&[elem] : list)\n"
1375               "    return 0;\n"
1376               "}");
1377  verifyFormat(
1378      "int f() {\n"
1379      "  for (auto /**/ const /**/ volatile /**/ && /**/ [elem] : list)\n"
1380      "    return 0;\n"
1381      "}");
1382}
1383
1384// end namespace
1385// end namespace format
1386// end namespace clang
1387