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