// 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() {}
