// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "gen/thing.h"
namespace v8 {
class InterfaceOutsideOfBlink {
public:
virtual void nonBlinkVirtual() = 0;
};
} // namespace v8
namespace blink {
class InsideOfBlink : public v8::InterfaceOutsideOfBlink {
public:
// This function overrides something outside of blink so don't rename it.
void nonBlinkVirtual() override {}
// This function is in blink so rename it.
virtual void BlinkVirtual() {}
};
class MyIterator {};
using my_iterator = char*;
class Task {
public:
// Already style-compliant methods shouldn't change.
void OutputDebugString() {}
// Tests that the declarations for methods are updated.
void DoTheWork();
// Overload to test using declarations that introduce multiple shadow
// declarations.
void DoTheWork(int);
virtual void ReallyDoTheWork() = 0;
// Note: this is purposely copyable and assignable, to make sure the Clang
// tool doesn't try to emit replacements for things that aren't explicitly
// written.
// Overloaded operators should not be rewritten.
Task& operator++() { return *this; }
// Conversion functions should not be rewritten.
explicit operator int() const { return 42; }
// These are special functions that we don't rename so that range-based
// for loops and STL things work.
MyIterator begin() { return {}; }
my_iterator end() { return {}; }
my_iterator rbegin() { return {}; }
MyIterator rend() { return {}; }
// The trace() method is used by Oilpan, but we plan to tweak the Oilpan's
// clang plugin, so that it recognizes the new method name.
void Trace() {}
// These are used by std::unique_lock and std::lock_guard.
void lock() {}
void unlock() {}
void try_lock() {}
};
class Other {
// Static begin/end/trace don't count, and should be renamed.
static MyIterator Begin() { return {}; }
static my_iterator End() { return {}; }
static void Trace() {}
static void Lock() {}
};
// Test that the actual method definition is also updated.
void Task::DoTheWork() {
ReallyDoTheWork();
}
template <typename T>
class Testable {
public:
typedef T Testable::*UnspecifiedBoolType;
// This method has a reference to a member in a "member context" and a
// "non-member context" to verify both are rewritten.
operator UnspecifiedBoolType() { return ptr_ ? &Testable::ptr_ : 0; }
private:
int ptr_;
};
namespace subname {
class SubnameParent {
virtual void SubnameMethod() {}
};
} // namespace subname
class SubnameChild : public subname::SubnameParent {
// This subclasses from blink::subname::SubnameParent and should be renamed.
void SubnameMethod() override {}
};
class GenChild : public blink::GenClass {
// This subclasses from the blink namespace but in the gen directory so it
// should not be renamed.
void genMethod() override {}
};
} // namespace blink
// Test that overrides from outside the Blink namespace are also updated.
class BovineTask : public blink::Task {
public:
using Task::DoTheWork;
void ReallyDoTheWork() override;
};
class SuperBovineTask : public BovineTask {
public:
using BovineTask::ReallyDoTheWork;
};
void BovineTask::ReallyDoTheWork() {
DoTheWork();
// Calls via an overridden method should also be updated.
ReallyDoTheWork();
}
// Finally, test that method pointers are also updated.
void F() {
void (blink::Task::*p1)() = &blink::Task::DoTheWork;
void (blink::Task::*p2)() = &BovineTask::DoTheWork;
void (blink::Task::*p3)() = &blink::Task::ReallyDoTheWork;
void (BovineTask::*p4)() = &BovineTask::ReallyDoTheWork;
}
bool G() {
// Use the Testable class to rewrite the method.
blink::Testable<int> tt;
return tt;
}
class SubclassOfInsideOfBlink : public blink::InsideOfBlink {
public:
// This function overrides something outside of blink so don't rename it.
void nonBlinkVirtual() override {}
// This function overrides something in blink so rename it.
void BlinkVirtual() override {}
};
class TestSubclassInsideOfBlink : public SubclassOfInsideOfBlink {
public:
public:
// This function overrides something outside of blink so don't rename it.
void nonBlinkVirtual() override {}
// This function overrides something in blink so rename it.
void BlinkVirtual() override {}
};
namespace blink {
struct StructInBlink {
// Structs in blink should rename their methods to capitals.
bool Function() { return true; }
};
class BitVector {
public:
class OutOfLineBits {};
enum Foo { kBlah };
struct Bar {};
class Baz {};
class FooBar {};
// Should be renamed to GetReadyState, because of
// ShouldPrefixFunctionName heuristic.
int GetReadyState() { return 123; }
template <typename T>
class MyRefPtr {};
// Naive renaming will break the build, by leaving return type the same
// as the method name - to avoid this "Get" prefix needs to be prepended
// as suggested in https://crbug.com/582312#c17.
const OutOfLineBits* GetOutOfLineBits() const { return nullptr; }
Foo GetFoo() { return kBlah; }
const Bar& GetBar() const { return bar_; }
MyRefPtr<Baz> GetBaz() { return MyRefPtr<Baz>(); }
const MyRefPtr<FooBar>& GetFooBar() { return foobar_; }
private:
Bar bar_;
MyRefPtr<FooBar> foobar_;
};
namespace get_prefix_vs_inheritance {
// Regression test for https://crbug.com/673031:
// 1. |frame| accessor/method should be renamed in the same way for
// WebFrameImplBase and WebLocalFrameImpl.
// 2. Need to rename |frame| to |GetFrame| (not to |Frame|) to avoid
// a conflict with the Frame type.
class FrameFoo {};
class LocalFrame : public FrameFoo {};
class WebFrameImplBase {
public:
// Using |frameFoo| to test inheritance, and NOT just the presence on the
// ShouldPrefixFunctionName list.
virtual FrameFoo* GetFrameFoo() const = 0;
};
class WebLocalFrameImpl : public WebFrameImplBase {
public:
LocalFrame* GetFrameFoo() const override { return nullptr; }
};
// This is also a regression test for https://crbug.com/673031. We should NOT
// rewrite in a non-virtual case, because walking the inheritance chain of the
// return type depends too much on unrelated context (i.e. walking the
// inheritance chain might not be possible if the return type is
// forward-declared).
class LayoutObjectFoo {};
class LayoutBoxModelObject : public LayoutObjectFoo {};
class PaintLayerStackingNode {
public:
// |layoutObjectFoo| should NOT be renamed to |GetLayoutObjectFoo| (just to
// |LayoutObjectFoo|) - see the big comment above. We use layoutObject*Foo*
// to test inheritance-related behavior and avoid testing whether method name
// is covered via ShouldPrefixFunctionName.
LayoutBoxModelObject* LayoutObjectFoo() { return nullptr; }
};
} // namespace get_prefix_vs_inheritance
namespace blacklisting_of_method_and_function_names {
class Foo {
// Expecting |swap| method to be renamed to |Swap| - we blacklist renaming of
// |swap| *function*, because it needs to have the same casing as std::swap,
// so that ADL can kick-in and pull it from another namespace depending on the
// bargument. We have a choice to rename or not rename |swap| *methods* - we
// chose to rename to be consistent (i.e. we rename |clear| -> |Clear|) and
// because Google C++ Styke Guide uses "Swap" in examples.
void Swap() {}
static void Swap(Foo& x, Foo& y) {}
// We don't rename |begin|, so that <algorithms> and other templates that
// expect |begin|, |end|, etc. continue to work. This is only necessary
// for instance methods - renaming static methods and funcitons is okay.
void begin() {}
static void Begin(int x) {}
// https://crbug.com672902: std-like names should not be rewritten.
void emplace_back(int x) {}
void insert(int x) {}
void push_back(int x) {}
int* back() { return nullptr; }
int* front() { return nullptr; }
void erase() {}
bool empty() { return true; }
};
void Begin(int x) {}
void swap(Foo& x, Foo& y) {}
} // blacklisting_of_method_and_function_names
} // namespace blink
namespace WTF {
struct StructInWTF {
// Structs in WTF should rename their methods to capitals.
bool Function() { return true; }
};
} // namespace WTF
void F2() {
blink::StructInBlink b;
b.Function();
WTF::StructInWTF w;
w.Function();
}
namespace blink {
class ClassDeclaredInsideBlink {
public:
static void MethodDefinedOutsideBlink();
};
namespace internal {
class InternalClass {
public:
static void Method();
};
} // namespace internal
// Tests for --method-blocklist cmdline parameter.
class IdlTestClass {
public:
static int NotBlocklistedMethod() { return 123; }
int NotBlocklistedMethod(int x) { return 123; }
static int idlStaticMethod() { return 123; }
int idlInstanceMethod() { return 123; }
template <typename T>
int idlTemplateMethod(T x) {
return 123;
}
};
template <typename T>
class IdlTemplateClass {
public:
int idlInstanceMethod(T x) { return 123; }
};
} // namespace blink
// https://crbug.com/640688 - need to rewrite method name below.
void blink::ClassDeclaredInsideBlink::MethodDefinedOutsideBlink() {}
void blink::internal::InternalClass::Method() {}