1 | //===-- ObjCMemberwiseInitializerTests.cpp ----------------------*- C++ -*-===// |
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 "TestTU.h" |
10 | #include "TweakTesting.h" |
11 | #include "gmock/gmock-matchers.h" |
12 | #include "gmock/gmock.h" |
13 | #include "gtest/gtest.h" |
14 | |
15 | namespace clang { |
16 | namespace clangd { |
17 | namespace { |
18 | |
19 | TWEAK_TEST(ObjCMemberwiseInitializer); |
20 | |
21 | TEST_F(ObjCMemberwiseInitializerTest, TestAvailability) { |
22 | FileName = "TestTU.m" ; |
23 | |
24 | // Ensure the action can't be triggered since arc is disabled. |
25 | EXPECT_UNAVAILABLE(R"cpp( |
26 | @interface Fo^o |
27 | @end |
28 | )cpp" ); |
29 | |
30 | ExtraArgs.push_back(x: "-fobjc-runtime=macosx" ); |
31 | ExtraArgs.push_back(x: "-fobjc-arc" ); |
32 | |
33 | // Ensure the action can be initiated on the interface and implementation, |
34 | // but not on the forward declaration. |
35 | EXPECT_AVAILABLE(R"cpp( |
36 | @interface Fo^o |
37 | @end |
38 | )cpp" ); |
39 | EXPECT_AVAILABLE(R"cpp( |
40 | @interface Foo |
41 | @end |
42 | |
43 | @implementation F^oo |
44 | @end |
45 | )cpp" ); |
46 | EXPECT_UNAVAILABLE("@class Fo^o;" ); |
47 | |
48 | // Ensure that the action can be triggered on ivars and properties, |
49 | // including selecting both. |
50 | EXPECT_AVAILABLE(R"cpp( |
51 | @interface Foo { |
52 | id _fi^eld; |
53 | } |
54 | @end |
55 | )cpp" ); |
56 | EXPECT_AVAILABLE(R"cpp( |
57 | @interface Foo |
58 | @property(nonatomic) id fi^eld; |
59 | @end |
60 | )cpp" ); |
61 | EXPECT_AVAILABLE(R"cpp( |
62 | @interface Foo { |
63 | id _fi^eld; |
64 | } |
65 | @property(nonatomic) id pr^op; |
66 | @end |
67 | )cpp" ); |
68 | |
69 | // Ensure that the action can't be triggered on property synthesis |
70 | // and methods. |
71 | EXPECT_UNAVAILABLE(R"cpp( |
72 | @interface Foo |
73 | @property(nonatomic) id prop; |
74 | @end |
75 | |
76 | @implementation Foo |
77 | @dynamic pr^op; |
78 | @end |
79 | )cpp" ); |
80 | EXPECT_UNAVAILABLE(R"cpp( |
81 | @interface Foo |
82 | @end |
83 | |
84 | @implementation Foo |
85 | - (void)fo^o {} |
86 | @end |
87 | )cpp" ); |
88 | } |
89 | |
90 | TEST_F(ObjCMemberwiseInitializerTest, Test) { |
91 | FileName = "TestTU.m" ; |
92 | ExtraArgs.push_back(x: "-fobjc-runtime=macosx" ); |
93 | ExtraArgs.push_back(x: "-fobjc-arc" ); |
94 | |
95 | const char *Input = R"cpp( |
96 | @interface Foo { |
97 | id [[_field; |
98 | } |
99 | @property(nonatomic) id prop]]; |
100 | @property(nonatomic) id notSelected; |
101 | @end)cpp" ; |
102 | const char *Output = R"cpp( |
103 | @interface Foo { |
104 | id _field; |
105 | } |
106 | @property(nonatomic) id prop; |
107 | @property(nonatomic) id notSelected; |
108 | - (instancetype)initWithField:(id)field prop:(id)prop; |
109 | |
110 | @end)cpp" ; |
111 | EXPECT_EQ(apply(Input), Output); |
112 | |
113 | Input = R"cpp( |
114 | @interface Foo |
115 | @property(nonatomic, nullable) id somePrettyLongPropertyName; |
116 | @property(nonatomic, nonnull) id someReallyLongPropertyName; |
117 | @end |
118 | |
119 | @implementation F^oo |
120 | |
121 | - (instancetype)init { |
122 | return self; |
123 | } |
124 | |
125 | @end)cpp" ; |
126 | Output = R"cpp( |
127 | @interface Foo |
128 | @property(nonatomic, nullable) id somePrettyLongPropertyName; |
129 | @property(nonatomic, nonnull) id someReallyLongPropertyName; |
130 | - (instancetype)initWithSomePrettyLongPropertyName:(nullable id)somePrettyLongPropertyName someReallyLongPropertyName:(nonnull id)someReallyLongPropertyName; |
131 | |
132 | @end |
133 | |
134 | @implementation Foo |
135 | |
136 | - (instancetype)init { |
137 | return self; |
138 | } |
139 | |
140 | - (instancetype)initWithSomePrettyLongPropertyName:(nullable id)somePrettyLongPropertyName someReallyLongPropertyName:(nonnull id)someReallyLongPropertyName { |
141 | self = [super init]; |
142 | if (self) { |
143 | _somePrettyLongPropertyName = somePrettyLongPropertyName; |
144 | _someReallyLongPropertyName = someReallyLongPropertyName; |
145 | } |
146 | return self; |
147 | } |
148 | |
149 | @end)cpp" ; |
150 | EXPECT_EQ(apply(Input), Output); |
151 | } |
152 | |
153 | } // namespace |
154 | } // namespace clangd |
155 | } // namespace clang |
156 | |