1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "gen/thing.h"
6
7 namespace v8 {
8
9 class InterfaceOutsideOfBlink {
10 public:
11 virtual void nonBlinkVirtual() = 0;
12 };
13
14 } // namespace v8
15
16 namespace blink {
17
18 class InsideOfBlink : public v8::InterfaceOutsideOfBlink {
19 public:
20 // This function overrides something outside of blink so don't rename it.
nonBlinkVirtual()21 void nonBlinkVirtual() override {}
22 // This function is in blink so rename it.
blinkVirtual()23 virtual void blinkVirtual() {}
24 };
25
26 class MyIterator {};
27 using my_iterator = char*;
28
29 class Task {
30 public:
31 // Already style-compliant methods shouldn't change.
OutputDebugString()32 void OutputDebugString() {}
33
34 // Tests that the declarations for methods are updated.
35 void doTheWork();
36 // Overload to test using declarations that introduce multiple shadow
37 // declarations.
38 void doTheWork(int);
39 virtual void reallyDoTheWork() = 0;
40
41 // Note: this is purposely copyable and assignable, to make sure the Clang
42 // tool doesn't try to emit replacements for things that aren't explicitly
43 // written.
44
45 // Overloaded operators should not be rewritten.
operator ++()46 Task& operator++() {
47 return *this;
48 }
49
50 // Conversion functions should not be rewritten.
operator int() const51 explicit operator int() const {
52 return 42;
53 }
54
55 // These are special functions that we don't rename so that range-based
56 // for loops and STL things work.
begin()57 MyIterator begin() { return {}; }
end()58 my_iterator end() { return {}; }
rbegin()59 my_iterator rbegin() { return {}; }
rend()60 MyIterator rend() { return {}; }
61 // The trace() method is used by Oilpan, but we plan to tweak the Oilpan's
62 // clang plugin, so that it recognizes the new method name.
trace()63 void trace() {}
64 // These are used by std::unique_lock and std::lock_guard.
lock()65 void lock() {}
unlock()66 void unlock() {}
try_lock()67 void try_lock() {}
68 };
69
70 class Other {
71 // Static begin/end/trace don't count, and should be renamed.
begin()72 static MyIterator begin() { return {}; }
end()73 static my_iterator end() { return {}; }
trace()74 static void trace() {}
lock()75 static void lock() {}
76 };
77
78 // Test that the actual method definition is also updated.
doTheWork()79 void Task::doTheWork() {
80 reallyDoTheWork();
81 }
82
83 template <typename T>
84 class Testable {
85 public:
86 typedef T Testable::*UnspecifiedBoolType;
87 // This method has a reference to a member in a "member context" and a
88 // "non-member context" to verify both are rewritten.
operator UnspecifiedBoolType()89 operator UnspecifiedBoolType() { return m_ptr ? &Testable::m_ptr : 0; }
90
91 private:
92 int m_ptr;
93 };
94
95 namespace subname {
96
97 class SubnameParent {
subnameMethod()98 virtual void subnameMethod() {}
99 };
100
101 } // namespace subname
102
103 class SubnameChild : public subname::SubnameParent {
104 // This subclasses from blink::subname::SubnameParent and should be renamed.
subnameMethod()105 void subnameMethod() override {}
106 };
107
108 class GenChild : public blink::GenClass {
109 // This subclasses from the blink namespace but in the gen directory so it
110 // should not be renamed.
genMethod()111 void genMethod() override {}
112 };
113
114 } // namespace blink
115
116 // Test that overrides from outside the Blink namespace are also updated.
117 class BovineTask : public blink::Task {
118 public:
119 using Task::doTheWork;
120 void reallyDoTheWork() override;
121 };
122
123 class SuperBovineTask : public BovineTask {
124 public:
125 using BovineTask::reallyDoTheWork;
126 };
127
reallyDoTheWork()128 void BovineTask::reallyDoTheWork() {
129 doTheWork();
130 // Calls via an overridden method should also be updated.
131 reallyDoTheWork();
132 }
133
134 // Finally, test that method pointers are also updated.
F()135 void F() {
136 void (blink::Task::*p1)() = &blink::Task::doTheWork;
137 void (blink::Task::*p2)() = &BovineTask::doTheWork;
138 void (blink::Task::*p3)() = &blink::Task::reallyDoTheWork;
139 void (BovineTask::*p4)() = &BovineTask::reallyDoTheWork;
140 }
141
G()142 bool G() {
143 // Use the Testable class to rewrite the method.
144 blink::Testable<int> tt;
145 return tt;
146 }
147
148 class SubclassOfInsideOfBlink : public blink::InsideOfBlink {
149 public:
150 // This function overrides something outside of blink so don't rename it.
nonBlinkVirtual()151 void nonBlinkVirtual() override {}
152 // This function overrides something in blink so rename it.
blinkVirtual()153 void blinkVirtual() override {}
154 };
155
156 class TestSubclassInsideOfBlink : public SubclassOfInsideOfBlink {
157 public:
158 public:
159 // This function overrides something outside of blink so don't rename it.
nonBlinkVirtual()160 void nonBlinkVirtual() override {}
161 // This function overrides something in blink so rename it.
blinkVirtual()162 void blinkVirtual() override {}
163 };
164
165 namespace blink {
166
167 struct StructInBlink {
168 // Structs in blink should rename their methods to capitals.
functionblink::StructInBlink169 bool function() { return true; }
170 };
171
172 class BitVector {
173 public:
174 class OutOfLineBits {};
175 enum Foo { Blah };
176 struct Bar {};
177 class Baz {};
178 class FooBar {};
179
180 // Should be renamed to GetReadyState, because of
181 // ShouldPrefixFunctionName heuristic.
readyState()182 int readyState() { return 123; }
183
184 template <typename T>
185 class MyRefPtr {};
186
187 // Naive renaming will break the build, by leaving return type the same
188 // as the method name - to avoid this "Get" prefix needs to be prepended
189 // as suggested in https://crbug.com/582312#c17.
outOfLineBits() const190 const OutOfLineBits* outOfLineBits() const { return nullptr; }
foo()191 Foo foo() { return Blah; }
bar() const192 const Bar& bar() const { return m_bar; }
baz()193 MyRefPtr<Baz> baz() { return MyRefPtr<Baz>(); }
fooBar()194 const MyRefPtr<FooBar>& fooBar() { return foobar_; }
195
196 private:
197 Bar m_bar;
198 MyRefPtr<FooBar> foobar_;
199 };
200
201 namespace get_prefix_vs_inheritance {
202
203 // Regression test for https://crbug.com/673031:
204 // 1. |frame| accessor/method should be renamed in the same way for
205 // WebFrameImplBase and WebLocalFrameImpl.
206 // 2. Need to rename |frame| to |GetFrame| (not to |Frame|) to avoid
207 // a conflict with the Frame type.
208
209 class FrameFoo {};
210 class LocalFrame : public FrameFoo {};
211
212 class WebFrameImplBase {
213 public:
214 // Using |frameFoo| to test inheritance, and NOT just the presence on the
215 // ShouldPrefixFunctionName list.
216 virtual FrameFoo* frameFoo() const = 0;
217 };
218
219 class WebLocalFrameImpl : public WebFrameImplBase {
220 public:
frameFoo() const221 LocalFrame* frameFoo() const override { return nullptr; }
222 };
223
224 // This is also a regression test for https://crbug.com/673031. We should NOT
225 // rewrite in a non-virtual case, because walking the inheritance chain of the
226 // return type depends too much on unrelated context (i.e. walking the
227 // inheritance chain might not be possible if the return type is
228 // forward-declared).
229 class LayoutObjectFoo {};
230 class LayoutBoxModelObject : public LayoutObjectFoo {};
231 class PaintLayerStackingNode {
232 public:
233 // |layoutObjectFoo| should NOT be renamed to |GetLayoutObjectFoo| (just to
234 // |LayoutObjectFoo|) - see the big comment above. We use layoutObject*Foo*
235 // to test inheritance-related behavior and avoid testing whether method name
236 // is covered via ShouldPrefixFunctionName.
layoutObjectFoo()237 LayoutBoxModelObject* layoutObjectFoo() { return nullptr; }
238 };
239
240 } // namespace get_prefix_vs_inheritance
241
242 namespace blacklisting_of_method_and_function_names {
243
244 class Foo {
245 // Expecting |swap| method to be renamed to |Swap| - we blacklist renaming of
246 // |swap| *function*, because it needs to have the same casing as std::swap,
247 // so that ADL can kick-in and pull it from another namespace depending on the
248 // bargument. We have a choice to rename or not rename |swap| *methods* - we
249 // chose to rename to be consistent (i.e. we rename |clear| -> |Clear|) and
250 // because Google C++ Styke Guide uses "Swap" in examples.
swap()251 void swap() {}
swap(Foo & x,Foo & y)252 static void swap(Foo& x, Foo& y) {}
253
254 // We don't rename |begin|, so that <algorithms> and other templates that
255 // expect |begin|, |end|, etc. continue to work. This is only necessary
256 // for instance methods - renaming static methods and funcitons is okay.
begin()257 void begin() {}
begin(int x)258 static void begin(int x) {}
259
260 // https://crbug.com672902: std-like names should not be rewritten.
emplace_back(int x)261 void emplace_back(int x) {}
insert(int x)262 void insert(int x) {}
push_back(int x)263 void push_back(int x) {}
back()264 int* back() { return nullptr; }
front()265 int* front() { return nullptr; }
erase()266 void erase() {}
empty()267 bool empty() { return true; }
268 };
269
begin(int x)270 void begin(int x) {}
swap(Foo & x,Foo & y)271 void swap(Foo& x, Foo& y) {}
272
273 } // blacklisting_of_method_and_function_names
274
275 } // namespace blink
276
277 namespace WTF {
278
279 struct StructInWTF {
280 // Structs in WTF should rename their methods to capitals.
functionWTF::StructInWTF281 bool function() { return true; }
282 };
283
284 } // namespace WTF
285
F2()286 void F2() {
287 blink::StructInBlink b;
288 b.function();
289 WTF::StructInWTF w;
290 w.function();
291 }
292
293 namespace blink {
294
295 class ClassDeclaredInsideBlink {
296 public:
297 static void methodDefinedOutsideBlink();
298 };
299
300 namespace internal {
301
302 class InternalClass {
303 public:
304 static void method();
305 };
306
307 } // namespace internal
308
309 // Tests for --method-blocklist cmdline parameter.
310 class IdlTestClass {
311 public:
notBlocklistedMethod()312 static int notBlocklistedMethod() { return 123; }
notBlocklistedMethod(int x)313 int notBlocklistedMethod(int x) { return 123; }
314
idlStaticMethod()315 static int idlStaticMethod() { return 123; }
idlInstanceMethod()316 int idlInstanceMethod() { return 123; }
317
318 template <typename T>
idlTemplateMethod(T x)319 int idlTemplateMethod(T x) {
320 return 123;
321 }
322 };
323
324 template <typename T>
325 class IdlTemplateClass {
326 public:
idlInstanceMethod(T x)327 int idlInstanceMethod(T x) { return 123; }
328 };
329
330 } // namespace blink
331
332 // https://crbug.com/640688 - need to rewrite method name below.
methodDefinedOutsideBlink()333 void blink::ClassDeclaredInsideBlink::methodDefinedOutsideBlink() {}
method()334 void blink::internal::InternalClass::method() {}
335