brintos

brintos / llvm-project-archived public Read only

0
0
Text · 19.3 KiB · 9f852e4 Raw
424 lines · cpp
1//===- unittest/Format/ObjCPropertyAttributeOrderFixerTest.cpp - unit tests2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "../lib/Format/ObjCPropertyAttributeOrderFixer.h"10#include "FormatTestBase.h"11#include "TestLexer.h"12 13#define DEBUG_TYPE "format-objc-property-attribute-order-fixer-test"14 15namespace clang {16namespace format {17namespace test {18namespace {19 20#define CHECK_PARSE(TEXT, FIELD, VALUE)                                        \21  EXPECT_NE(VALUE, Style.FIELD) << "Initial value already the same!";          \22  EXPECT_EQ(0, parseConfiguration(TEXT, &Style).value());                      \23  EXPECT_EQ(VALUE, Style.FIELD) << "Unexpected value after parsing!"24 25#define FAIL_PARSE(TEXT, FIELD, VALUE)                                         \26  EXPECT_NE(0, parseConfiguration(TEXT, &Style).value());                      \27  EXPECT_EQ(VALUE, Style.FIELD) << "Unexpected value after parsing!"28 29class ObjCPropertyAttributeOrderFixerTest : public FormatTestBase {30protected:31  TokenList annotate(StringRef Code,32                     const FormatStyle &Style = getLLVMStyle()) {33    return TestLexer(Allocator, Buffers, Style).annotate(Code);34  }35 36  llvm::SpecificBumpPtrAllocator<FormatToken> Allocator;37  std::vector<std::unique_ptr<llvm::MemoryBuffer>> Buffers;38};39 40TEST_F(ObjCPropertyAttributeOrderFixerTest, ParsesStyleOption) {41  FormatStyle Style = {};42  Style.Language = FormatStyle::LK_ObjC;43 44  CHECK_PARSE("ObjCPropertyAttributeOrder: [class]", ObjCPropertyAttributeOrder,45              std::vector<std::string>({"class"}));46 47  CHECK_PARSE("ObjCPropertyAttributeOrder: ["48              "class, direct, atomic, nonatomic, "49              "assign, retain, strong, copy, weak, unsafe_unretained, "50              "readonly, readwrite, getter, setter, "51              "nullable, nonnull, null_resettable, null_unspecified"52              "]",53              ObjCPropertyAttributeOrder,54              std::vector<std::string>({55                  "class",56                  "direct",57                  "atomic",58                  "nonatomic",59                  "assign",60                  "retain",61                  "strong",62                  "copy",63                  "weak",64                  "unsafe_unretained",65                  "readonly",66                  "readwrite",67                  "getter",68                  "setter",69                  "nullable",70                  "nonnull",71                  "null_resettable",72                  "null_unspecified",73              }));74}75 76TEST_F(ObjCPropertyAttributeOrderFixerTest, SortsSpecifiedAttributes) {77  FormatStyle Style = getLLVMStyle();78  Style.Language = FormatStyle::LK_ObjC;79  Style.ObjCPropertyAttributeOrder = {"a", "b", "c"};80 81  // Zero: nothing to do, but is legal.82  verifyFormat("@property() int p;", Style);83 84  // One: shouldn't move.85  verifyFormat("@property(a) int p;", Style);86  verifyFormat("@property(b) int p;", Style);87  verifyFormat("@property(c) int p;", Style);88 89  // Two in correct order already: no change.90  verifyFormat("@property(a, b) int p;", Style);91  verifyFormat("@property(a, c) int p;", Style);92  verifyFormat("@property(b, c) int p;", Style);93 94  // Three in correct order already: no change.95  verifyFormat("@property(a, b, c) int p;", Style);96 97  // Two wrong order.98  verifyFormat("@property(a, b) int p;", "@property(b, a) int p;", Style);99  verifyFormat("@property(a, c) int p;", "@property(c, a) int p;", Style);100  verifyFormat("@property(b, c) int p;", "@property(c, b) int p;", Style);101 102  // Three wrong order.103  verifyFormat("@property(a, b, c) int p;", "@property(b, a, c) int p;", Style);104  verifyFormat("@property(a, b, c) int p;", "@property(c, b, a) int p;", Style);105 106  // Check that properties preceded by @optional/@required work.107  verifyFormat("@optional\n"108               "@property(a, b) int p;",109               "@optional @property(b, a) int p;", Style);110  verifyFormat("@required\n"111               "@property(a, b) int p;",112               "@required @property(b, a) int p;", Style);113 114  // Check two `@property`s on one-line are reflowed (by other passes)115  // and both have their attributes reordered.116  verifyFormat("@property(a, b) int p;\n"117               "@property(a, b) int q;",118               "@property(b, a) int p; @property(b, a) int q;", Style);119}120 121TEST_F(ObjCPropertyAttributeOrderFixerTest, SortsAttributesWithValues) {122  FormatStyle Style = getLLVMStyle();123  Style.Language = FormatStyle::LK_ObjC;124  Style.ObjCPropertyAttributeOrder = {"a", "getter", "c"};125 126  // No change127  verifyFormat("@property(getter=G, c) int p;", Style);128  verifyFormat("@property(a, getter=G) int p;", Style);129  verifyFormat("@property(a, getter=G, c) int p;", Style);130 131  // Reorder132  verifyFormat("@property(getter=G, c) int p;", "@property(c, getter=G) int p;",133               Style);134  verifyFormat("@property(a, getter=G) int p;", "@property(getter=G, a) int p;",135               Style);136  verifyFormat("@property(a, getter=G, c) int p;",137               "@property(getter=G, c, a) int p;", Style);138 139  // Multiple set properties, including ones not recognized140  verifyFormat("@property(a=A, c=C, x=X, y=Y) int p;",141               "@property(c=C, x=X, y=Y, a=A) int p;", Style);142}143 144TEST_F(ObjCPropertyAttributeOrderFixerTest, SortsUnspecifiedAttributesToBack) {145  FormatStyle Style = getLLVMStyle();146  Style.Language = FormatStyle::LK_ObjC;147  Style.ObjCPropertyAttributeOrder = {"a", "b", "c"};148 149  verifyFormat("@property(x) int p;", Style);150 151  // No change in order.152  verifyFormat("@property(a, x, y) int p;", Style);153  verifyFormat("@property(b, x, y) int p;", Style);154  verifyFormat("@property(a, b, c, x, y) int p;", Style);155 156  // Reorder one unrecognized one.157  verifyFormat("@property(a, x) int p;", "@property(x, a) int p;", Style);158 159  // Prove the unrecognized ones have a stable sort order160  verifyFormat("@property(a, b, x, y) int p;", "@property(x, b, y, a) int p;",161               Style);162  verifyFormat("@property(a, b, y, x) int p;", "@property(y, b, x, a) int p;",163               Style);164}165 166TEST_F(ObjCPropertyAttributeOrderFixerTest, HandlesDuplicatedAttributes) {167  // Duplicated attributes aren't rejected by the compiler even if it's silly168  // to do so. Preserve them and sort them best-effort.169  FormatStyle Style = getLLVMStyle();170  Style.Language = FormatStyle::LK_ObjC;171  Style.ObjCPropertyAttributeOrder = {"a", "b", "c"};172 173  // Just a dup and nothing else.174  verifyFormat("@property(a) int p;", "@property(a, a) int p;", Style);175 176  // A dup and something else.177  verifyFormat("@property(a, b) int p;", "@property(a, b, a) int p;", Style);178 179  // Duplicates using `=`.180  verifyFormat("@property(a=A, b=X) int p;",181               "@property(a=A, b=X, a=A, b=Y) int p;", Style);182  verifyFormat("@property(a=A, b=Y) int p;",183               "@property(a=A, b=Y, a=A, b=X) int p;", Style);184  verifyFormat("@property(a, b=B) int p;", "@property(a, b=B, a=A, b) int p;",185               Style);186}187 188TEST_F(ObjCPropertyAttributeOrderFixerTest, SortsInPPDirective) {189  FormatStyle Style = getLLVMStyle();190  Style.Language = FormatStyle::LK_ObjC;191  Style.ObjCPropertyAttributeOrder = {"a", "b", "c"};192 193  // Spot-check a few simple cases that require sorting in a macro definition.194  verifyFormat("#define MACRO @property() int p;", Style);195  verifyFormat("#define MACRO @property(a) int p;", Style);196  verifyFormat("#define MACRO @property(a, b) int p;",197               "#define MACRO @property(b, a) int p;", Style);198  verifyFormat("#define MACRO @property(a, b, c) int p;",199               "#define MACRO @property(c, b, a) int p;", Style);200}201 202TEST_F(ObjCPropertyAttributeOrderFixerTest, HandlesAllAttributes) {203  // `class` is the only attribute that is a keyword, so make sure it works too.204  FormatStyle Style = getLLVMStyle();205  Style.Language = FormatStyle::LK_ObjC;206  Style.ObjCPropertyAttributeOrder = {"FIRST",207                                      "class",208                                      "direct",209                                      "atomic",210                                      "nonatomic",211                                      "assign",212                                      "retain",213                                      "strong",214                                      "copy",215                                      "weak",216                                      "unsafe_unretained",217                                      "readonly",218                                      "readwrite",219                                      "getter",220                                      "setter",221                                      "nullable",222                                      "nonnull",223                                      "null_resettable",224                                      "null_unspecified",225                                      "LAST"};226 227  // No change: specify all attributes in the correct order.228  verifyFormat("@property(class, LAST) int p;", Style);229  verifyFormat("@property(direct, LAST) int p;", Style);230  verifyFormat("@property(atomic, LAST) int p;", Style);231  verifyFormat("@property(nonatomic, LAST) int p;", Style);232  verifyFormat("@property(assign, LAST) int p;", Style);233  verifyFormat("@property(retain, LAST) int p;", Style);234  verifyFormat("@property(strong, LAST) int p;", Style);235  verifyFormat("@property(copy, LAST) int p;", Style);236  verifyFormat("@property(weak, LAST) int p;", Style);237  verifyFormat("@property(unsafe_unretained, LAST) int p;", Style);238  verifyFormat("@property(readonly, LAST) int p;", Style);239  verifyFormat("@property(readwrite, LAST) int p;", Style);240  verifyFormat("@property(getter, LAST) int p;", Style);241  verifyFormat("@property(setter, LAST) int p;", Style);242  verifyFormat("@property(nullable, LAST) int p;", Style);243  verifyFormat("@property(nonnull, LAST) int p;", Style);244  verifyFormat("@property(null_resettable, LAST) int p;", Style);245  verifyFormat("@property(null_unspecified, LAST) int p;", Style);246 247  verifyFormat("@property(FIRST, class) int p;", Style);248  verifyFormat("@property(FIRST, direct) int p;", Style);249  verifyFormat("@property(FIRST, atomic) int p;", Style);250  verifyFormat("@property(FIRST, nonatomic) int p;", Style);251  verifyFormat("@property(FIRST, assign) int p;", Style);252  verifyFormat("@property(FIRST, retain) int p;", Style);253  verifyFormat("@property(FIRST, strong) int p;", Style);254  verifyFormat("@property(FIRST, copy) int p;", Style);255  verifyFormat("@property(FIRST, weak) int p;", Style);256  verifyFormat("@property(FIRST, unsafe_unretained) int p;", Style);257  verifyFormat("@property(FIRST, readonly) int p;", Style);258  verifyFormat("@property(FIRST, readwrite) int p;", Style);259  verifyFormat("@property(FIRST, getter) int p;", Style);260  verifyFormat("@property(FIRST, setter) int p;", Style);261  verifyFormat("@property(FIRST, nullable) int p;", Style);262  verifyFormat("@property(FIRST, nonnull) int p;", Style);263  verifyFormat("@property(FIRST, null_resettable) int p;", Style);264  verifyFormat("@property(FIRST, null_unspecified) int p;", Style);265 266  verifyFormat("@property(FIRST, class, LAST) int p;", Style);267  verifyFormat("@property(FIRST, direct, LAST) int p;", Style);268  verifyFormat("@property(FIRST, atomic, LAST) int p;", Style);269  verifyFormat("@property(FIRST, nonatomic, LAST) int p;", Style);270  verifyFormat("@property(FIRST, assign, LAST) int p;", Style);271  verifyFormat("@property(FIRST, retain, LAST) int p;", Style);272  verifyFormat("@property(FIRST, strong, LAST) int p;", Style);273  verifyFormat("@property(FIRST, copy, LAST) int p;", Style);274  verifyFormat("@property(FIRST, weak, LAST) int p;", Style);275  verifyFormat("@property(FIRST, unsafe_unretained, LAST) int p;", Style);276  verifyFormat("@property(FIRST, readonly, LAST) int p;", Style);277  verifyFormat("@property(FIRST, readwrite, LAST) int p;", Style);278  verifyFormat("@property(FIRST, getter, LAST) int p;", Style);279  verifyFormat("@property(FIRST, setter, LAST) int p;", Style);280  verifyFormat("@property(FIRST, nullable, LAST) int p;", Style);281  verifyFormat("@property(FIRST, nonnull, LAST) int p;", Style);282  verifyFormat("@property(FIRST, null_resettable, LAST) int p;", Style);283  verifyFormat("@property(FIRST, null_unspecified, LAST) int p;", Style);284 285  // Reorder: put `FIRST` and/or `LAST` in the wrong spot.286  verifyFormat("@property(class, LAST) int p;", "@property(LAST, class) int p;",287               Style);288  verifyFormat("@property(direct, LAST) int p;",289               "@property(LAST, direct) int p;", Style);290  verifyFormat("@property(atomic, LAST) int p;",291               "@property(LAST, atomic) int p;", Style);292  verifyFormat("@property(nonatomic, LAST) int p;",293               "@property(LAST, nonatomic) int p;", Style);294  verifyFormat("@property(assign, LAST) int p;",295               "@property(LAST, assign) int p;", Style);296  verifyFormat("@property(retain, LAST) int p;",297               "@property(LAST, retain) int p;", Style);298  verifyFormat("@property(strong, LAST) int p;",299               "@property(LAST, strong) int p;", Style);300  verifyFormat("@property(copy, LAST) int p;", "@property(LAST, copy) int p;",301               Style);302  verifyFormat("@property(weak, LAST) int p;", "@property(LAST, weak) int p;",303               Style);304  verifyFormat("@property(unsafe_unretained, LAST) int p;",305               "@property(LAST, unsafe_unretained) int p;", Style);306  verifyFormat("@property(readonly, LAST) int p;",307               "@property(LAST, readonly) int p;", Style);308  verifyFormat("@property(readwrite, LAST) int p;",309               "@property(LAST, readwrite) int p;", Style);310  verifyFormat("@property(getter, LAST) int p;",311               "@property(LAST, getter) int p;", Style);312  verifyFormat("@property(setter, LAST) int p;",313               "@property(LAST, setter) int p;", Style);314  verifyFormat("@property(nullable, LAST) int p;",315               "@property(LAST, nullable) int p;", Style);316  verifyFormat("@property(nonnull, LAST) int p;",317               "@property(LAST, nonnull) int p;", Style);318  verifyFormat("@property(null_resettable, LAST) int p;",319               "@property(LAST, null_resettable) int p;", Style);320  verifyFormat("@property(null_unspecified, LAST) int p;",321               "@property(LAST, null_unspecified) int p;", Style);322 323  verifyFormat("@property(FIRST, class) int p;",324               "@property(class, FIRST) int p;", Style);325  verifyFormat("@property(FIRST, direct) int p;",326               "@property(direct, FIRST) int p;", Style);327  verifyFormat("@property(FIRST, atomic) int p;",328               "@property(atomic, FIRST) int p;", Style);329  verifyFormat("@property(FIRST, nonatomic) int p;",330               "@property(nonatomic, FIRST) int p;", Style);331  verifyFormat("@property(FIRST, assign) int p;",332               "@property(assign, FIRST) int p;", Style);333  verifyFormat("@property(FIRST, retain) int p;",334               "@property(retain, FIRST) int p;", Style);335  verifyFormat("@property(FIRST, strong) int p;",336               "@property(strong, FIRST) int p;", Style);337  verifyFormat("@property(FIRST, copy) int p;", "@property(copy, FIRST) int p;",338               Style);339  verifyFormat("@property(FIRST, weak) int p;", "@property(weak, FIRST) int p;",340               Style);341  verifyFormat("@property(FIRST, unsafe_unretained) int p;",342               "@property(unsafe_unretained, FIRST) int p;", Style);343  verifyFormat("@property(FIRST, readonly) int p;",344               "@property(readonly, FIRST) int p;", Style);345  verifyFormat("@property(FIRST, readwrite) int p;",346               "@property(readwrite, FIRST) int p;", Style);347  verifyFormat("@property(FIRST, getter) int p;",348               "@property(getter, FIRST) int p;", Style);349  verifyFormat("@property(FIRST, setter) int p;",350               "@property(setter, FIRST) int p;", Style);351  verifyFormat("@property(FIRST, nullable) int p;",352               "@property(nullable, FIRST) int p;", Style);353  verifyFormat("@property(FIRST, nonnull) int p;",354               "@property(nonnull, FIRST) int p;", Style);355  verifyFormat("@property(FIRST, null_resettable) int p;",356               "@property(null_resettable, FIRST) int p;", Style);357  verifyFormat("@property(FIRST, null_unspecified) int p;",358               "@property(null_unspecified, FIRST) int p;", Style);359 360  verifyFormat("@property(FIRST, class, LAST) int p;",361               "@property(LAST, class, FIRST) int p;", Style);362  verifyFormat("@property(FIRST, direct, LAST) int p;",363               "@property(LAST, direct, FIRST) int p;", Style);364  verifyFormat("@property(FIRST, atomic, LAST) int p;",365               "@property(LAST, atomic, FIRST) int p;", Style);366  verifyFormat("@property(FIRST, nonatomic, LAST) int p;",367               "@property(LAST, nonatomic, FIRST) int p;", Style);368  verifyFormat("@property(FIRST, assign, LAST) int p;",369               "@property(LAST, assign, FIRST) int p;", Style);370  verifyFormat("@property(FIRST, retain, LAST) int p;",371               "@property(LAST, retain, FIRST) int p;", Style);372  verifyFormat("@property(FIRST, strong, LAST) int p;",373               "@property(LAST, strong, FIRST) int p;", Style);374  verifyFormat("@property(FIRST, copy, LAST) int p;",375               "@property(LAST, copy, FIRST) int p;", Style);376  verifyFormat("@property(FIRST, weak, LAST) int p;",377               "@property(LAST, weak, FIRST) int p;", Style);378  verifyFormat("@property(FIRST, unsafe_unretained, LAST) int p;",379               "@property(LAST, unsafe_unretained, FIRST) int p;", Style);380  verifyFormat("@property(FIRST, readonly, LAST) int p;",381               "@property(LAST, readonly, FIRST) int p;", Style);382  verifyFormat("@property(FIRST, readwrite, LAST) int p;",383               "@property(LAST, readwrite, FIRST) int p;", Style);384  verifyFormat("@property(FIRST, getter, LAST) int p;",385               "@property(LAST, getter, FIRST) int p;", Style);386  verifyFormat("@property(FIRST, setter, LAST) int p;",387               "@property(LAST, setter, FIRST) int p;", Style);388  verifyFormat("@property(FIRST, nullable, LAST) int p;",389               "@property(LAST, nullable, FIRST) int p;", Style);390  verifyFormat("@property(FIRST, nonnull, LAST) int p;",391               "@property(LAST, nonnull, FIRST) int p;", Style);392  verifyFormat("@property(FIRST, null_resettable, LAST) int p;",393               "@property(LAST, null_resettable, FIRST) int p;", Style);394  verifyFormat("@property(FIRST, null_unspecified, LAST) int p;",395               "@property(LAST, null_unspecified, FIRST) int p;", Style);396}397 398TEST_F(ObjCPropertyAttributeOrderFixerTest, HandlesCommentsAroundAttributes) {399  FormatStyle Style = getLLVMStyle();400  Style.Language = FormatStyle::LK_ObjC;401  Style.ObjCPropertyAttributeOrder = {"a", "b"};402 403  // Zero attributes but comments.404  verifyFormat("@property(/* 1 */) int p;", Style);405  verifyFormat("@property(/* 1 */ /* 2 */) int p;", Style);406 407  // One attribute with comments before or after.408  verifyFormat("@property(/* 1 */ a) int p;", Style);409  verifyFormat("@property(a /* 2 */) int p;", Style);410  verifyFormat("@property(/* 1 */ a /* 2 */) int p;", Style);411 412  // No reordering if comments are encountered anywhere.413  // (Each case represents a reordering that would have happened414  // without the comment.)415  verifyFormat("@property(/* before */ b, a) int p;", Style);416  verifyFormat("@property(b, /* between */ a) int p;", Style);417  verifyFormat("@property(b, a /* after */) int p;", Style);418}419 420} // namespace421} // namespace test422} // namespace format423} // namespace clang424