1 | |
2 | |
3 | |
4 | |
5 | |
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 | |
21 | using clang::tooling::ReplacementTest; |
22 | |
23 | namespace clang { |
24 | namespace format { |
25 | namespace { |
26 | |
27 | class FormatTestObjC : public ::testing::Test { |
28 | protected: |
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::Range> Ranges(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 | |
71 | TEST(FormatTestObjCStyle, DetectsObjCInHeaders) { |
72 | auto Style = getStyle("LLVM", "a.h", "none", "@interface\n" |
73 | "- (id)init;"); |
74 | ASSERT_TRUE((bool)Style); |
75 | EXPECT_EQ(FormatStyle::LK_ObjC, Style->Language); |
76 | |
77 | Style = getStyle("LLVM", "a.h", "none", "@interface\n" |
78 | "+ (id)init;"); |
79 | ASSERT_TRUE((bool)Style); |
80 | EXPECT_EQ(FormatStyle::LK_ObjC, Style->Language); |
81 | |
82 | Style = getStyle("LLVM", "a.h", "none", "@interface\n" |
83 | "@end\n" |
84 | "//comment"); |
85 | ASSERT_TRUE((bool)Style); |
86 | EXPECT_EQ(FormatStyle::LK_ObjC, Style->Language); |
87 | |
88 | Style = getStyle("LLVM", "a.h", "none", "@interface\n" |
89 | "@end //comment"); |
90 | ASSERT_TRUE((bool)Style); |
91 | EXPECT_EQ(FormatStyle::LK_ObjC, Style->Language); |
92 | |
93 | |
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 | |
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 | |
168 | TEST(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 | |
182 | TEST_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 | |
197 | TEST_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 | |
216 | TEST_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 | |
227 | TEST_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 | |
246 | TEST_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 | |
403 | verifyFormat("void eeeeeeee(int eeeee, int eeeee,\n" |
404 | " int eeeee, int eeeee);\n"); |
405 | |
406 | verifyFormat("@interface fffffffffffff () <\n" |
407 | " fffffffffffff,\n" |
408 | " fffffffffffff,\n" |
409 | " fffffffffffff,\n" |
410 | " fffffffffffff> {\n" |
411 | "}"); |
412 | } |
413 | |
414 | TEST_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 | |
491 | TEST_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 | |
538 | TEST_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 | |
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 | |
578 | |
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 | |
586 | verifyFormat("- (void)shortf:(GTMFoo *)theFoo\n" |
587 | " aShortf:(NSRect)theRect {\n" |
588 | "}"); |
589 | |
590 | |
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 | |
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 | |
612 | TEST_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 | |
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 | |
634 | |
635 | |
636 | |
637 | verifyFormat("return (MyType *)[self.tableView cellForRowAtIndexPath:cell];"); |
638 | |
639 | |
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 | |
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 | |
708 | |
709 | |
710 | |
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 | |
718 | |
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 | |
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 | |
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 | |
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 | |
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 | |
848 | |
849 | verifyFormat("[[object block:^{\n" |
850 | " return 42;\n" |
851 | "}] a:42 b:42];"); |
852 | |
853 | verifyFormat("[[object block:^{\n" |
854 | " return 42;\n" |
855 | "}] aaaaaaa:42 b:42];"); |
856 | |
857 | verifyFormat("[[object block:^{\n" |
858 | " return 42;\n" |
859 | "}] aaaaaaa:42\n" |
860 | " bb:42];"); |
861 | |
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 | |
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 | |
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];"); |
903 | |
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 | |
922 | |
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 | |
942 | TEST_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 | |
972 | |
973 | verifyFormat("@ /*foo*/ interface"); |
974 | } |
975 | |
976 | TEST_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 | |
985 | TEST_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 | |
1030 | TEST_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 | |
1050 | TEST_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 | |
1125 | TEST_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 | |
1143 | TEST_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 | |
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 | |
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 | |
1232 | TEST_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" |
1261 | "];"); |
1262 | |
1263 | |
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 | |
1295 | |
1296 | verifyFormat("NSArray *foo = @[\n" |
1297 | " @\"aaaaaaaaaaaaaaaaaaaaaaaaaa\"\n" |
1298 | "];\n"); |
1299 | } |
1300 | |
1301 | TEST_F(FormatTestObjC, BreaksCallStatementWhereSemiJustOverTheLimit) { |
1302 | Style.ColumnLimit = 60; |
1303 | |
1304 | |
1305 | verifyFormat("int f(int a) {\n" |
1306 | " a = [self aaaaaaaaaa:bbbbbbbbb\n" |
1307 | " ccccccccc:dddddddd\n" |
1308 | " ee:fddd];\n" |
1309 | "}"); |
1310 | } |
1311 | |
1312 | TEST_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 | |
1332 | TEST_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 | |
1350 | |
1351 | |
1352 | |
1353 | |
1354 | |
1355 | |
1356 | |
1357 | |
1358 | } |
1359 | |
1360 | TEST_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 | } |
1385 | } |
1386 | } |
1387 | |