// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <stdint.h>  // for uintptr_t

#include <string>
#include <tuple>    // for std::tie
#include <utility>  // for std::swap

class SomeClass {};
class DerivedClass : public SomeClass {};

struct MyStruct {
  MyStruct(SomeClass& ref1, SomeClass& ref2, const SomeClass& ref3)
      : ref1_(ref1), ref2_(ref2), const_ref_(ref3) {}
  SomeClass* ptr;
  SomeClass* ptr2;
  const SomeClass* const_ptr;
  int (*func_ptr_field)();
  const char* const_char_ptr;

  // Expected rewrite: const raw_ref<SomeClass> ref1_;
  SomeClass& ref1_;
  // Expected rewrite: const raw_ref<SomeClass> ref2_;
  SomeClass& ref2_;
  // Expected rewrite: const raw_ref<const SomeClass> const_ref_;
  const SomeClass& const_ref_;
};

namespace auto_tests {

MyStruct* GetMyStruct() {
  return nullptr;
}

SomeClass* GetSomeClass() {
  return nullptr;
}

SomeClass* ConvertSomeClassToSomeClass(SomeClass* some_class) {
  return some_class;
}

void foo() {
  SomeClass s;
  MyStruct my_struct(s, s, s);

  // After the rewrite |my_struct.ptr_field| is no longer a pointer,
  // so |auto*| won't work.  We fix this up, by appending |.get()|.
  // Expected rewrite: auto* ptr_var = my_struct.ptr.get();
  auto* ptr_var = my_struct.ptr;

  // Tests for other kinds of initialization.
  // Expected rewrite: |.get()| should be appended in both cases below.
  auto* init_test1(my_struct.ptr);
  auto* init_test2{my_struct.ptr};

  // Test for handling of the |const| qualifier.
  // Expected rewrite: const auto* ptr_var = my_struct.ptr.get();
  const auto* const_ptr_var = my_struct.ptr;

  // More complicated initialization expression, but the |ptr_field| struct
  // member dereference is still the top/last expression here.
  // Expected rewrite: ...->ptr.get()
  auto* complicated_var = GetMyStruct()->ptr;

  // The test below covers:
  // 1. Two variables with single |auto|,
  // 2. Tricky placement of |*| (next to the variable name).
  // Expected rewrite: ...ptr.get()... (twice in the 2nd example).
  auto *ptr_var1 = my_struct.ptr, *ptr_var2 = GetSomeClass();
  auto *ptr_var3 = my_struct.ptr, *ptr_var4 = my_struct.ptr;
  auto *ptr_var5 = GetSomeClass(), *ptr_var6 = my_struct.ptr;

  // Test for the case where
  // 1. The resulting type is the same as in the |ptr_var| and |complicated_var|
  //    examples
  // 2. Deep in the initialization expression there is a member dereference
  //    of |ptr_field|
  // but
  // 3. The final/top-level initialization expression doesn't dereference
  //    |ptr_field|.
  // No rewrite expected.
  auto* not_affected_field_var = ConvertSomeClassToSomeClass(my_struct.ptr);

  // Test for pointer |auto| assigned from non-raw_ptr-elligible field.
  // No rewrite expected.
  auto* func_ptr_var = my_struct.func_ptr_field;

  // Test for non-pointer |auto| assigned from raw_ptr-elligible field.
  // No rewrite expected.
  auto non_pointer_auto_var = my_struct.ptr;

  // Test for non-auto pointer.
  // No rewrite expected.
  SomeClass* non_auto_ptr_var = my_struct.ptr;

  // raw_ref tests
  {
    SomeClass some_class;
    MyStruct s(some_class, some_class, some_class);

    // After the rewrite |my_struct.ref_1| is no longer a native reference,
    // so |auto&| won't do what's expected.  We fix this up, by injecting *
    // operator. Expected rewrite: auto& ptr_var = *(my_struct.ref1_);
    auto& ref_var = my_struct.ref1_;

    // Tests for other kinds of initialization.
    // Expected rewrite: operator* should be added in both cases below.
    auto& init_test1(my_struct.ref1_);
    auto& init_test2{my_struct.ref2_};

    // Test for handling of the |const| qualifier.
    // Expected rewrite: const auto& ptr_var = *my_struct.const_ref_;
    const auto& const_ref_var = my_struct.const_ref_;

    // More complicated initialization expression, but the |ref1_| struct
    // member dereference is still the top/last expression here.
    // Expected rewrite: *GetMyStruct()->ref1_
    auto& complicated_var = GetMyStruct()->ref1_;

    // The test below covers:
    // 1. Two variables with single |auto|,
    // 2. Tricky placement of |&| (next to the variable name).
    // Expected rewrite: *...ref_... (twice in the 2nd example).
    auto &ref_var1 = my_struct.ref1_, &ref_var2 = *GetSomeClass();
    auto &ref_var3 = my_struct.ref1_, &ref_var4 = my_struct.ref1_;
    auto &ref_var5 = *GetSomeClass(), &ref_var6 = my_struct.ref1_;

    // Expected rewrite: auto* not_affected_field_var =
    // ConvertSomeClassToSomeClass(&*my_struct.ref1_);
    auto* not_affected_field_var =
        ConvertSomeClassToSomeClass(&my_struct.ref1_);

    // Test for non-pointer |auto| assigned from raw_ref-eligible field.
    // expected rewrite: auto non_pointer_auto_var = *my_struct.ref1_;
    auto non_pointer_auto_var = my_struct.ref1_;

    // Test for non-auto pointer.
    // No rewrite expected.
    SomeClass& non_auto_ref_var = my_struct.ref1_;
  }
}

}  // namespace auto_tests

namespace printf_tests {

int ConvertSomeClassToInt(SomeClass* some_class) {
  return 123;
}

void MyPrintf(const char* fmt, ...) {}

void foo() {
  SomeClass some_class;
  MyStruct s(some_class, some_class, some_class);

  // Expected rewrite: MyPrintf("%p", s.ptr.get());
  MyPrintf("%p", s.ptr);

  // Test - all arguments are rewritten.
  // Expected rewrite: MyPrintf("%p, %p", s.ptr.get(), s.ptr2.get());
  MyPrintf("%p, %p", s.ptr, s.ptr2);

  // Test - only |s.ptr|-style arguments are rewritten.
  // Expected rewrite: MyPrintf("%d, %p", 123, s.ptr.get());
  MyPrintf("%d, %p", 123, s.ptr);

  // Test - |s.ptr| is deeply nested.
  // No rewrite expected.
  MyPrintf("%d", ConvertSomeClassToInt(s.ptr));
}

}  // namespace printf_tests

namespace cast_tests {

void foo() {
  SomeClass s;
  MyStruct my_struct(s, s, s);

  // To get |const_cast<...>(...)| to compile after the rewrite we
  // need to rewrite the casted expression.
  // Expected rewrite: const_cast<SomeClass*>(my_struct.const_ptr.get());
  SomeClass* v = const_cast<SomeClass*>(my_struct.const_ptr);
  // Expected rewrite: const_cast<const SomeClass*>(my_struct.ptr.get());
  const SomeClass* v2 = const_cast<const SomeClass*>(my_struct.ptr);

  // To get |reinterpret_cast<uintptr_t>(...)| to compile after the rewrite we
  // need to rewrite the casted expression.
  // Expected rewrite: reinterpret_cast<uintptr_t>(my_struct.ptr.get());
  uintptr_t u = reinterpret_cast<uintptr_t>(my_struct.ptr);

  // There is no need to append |.get()| inside static_cast - unlike the
  // const_cast and reinterpret_cast examples above, static_cast will compile
  // just fine.
  DerivedClass* d = static_cast<DerivedClass*>(my_struct.ptr);
  void* void_var = static_cast<void*>(my_struct.ptr);
}

void foo2() {
  SomeClass s;
  MyStruct my_struct(s, s, s);

  // To get |const_cast<...>(...)| to compile after the rewrite we
  // need to rewrite the casted expression.
  // Expected rewrite: const_cast<SomeClass&>(*my_struct.const_ref_);
  SomeClass& v = const_cast<SomeClass&>(my_struct.const_ref_);
  // Expected rewrite: const_cast<const SomeClass&>(*my_struct.ptr);
  const SomeClass& v2 = const_cast<const SomeClass&>(my_struct.ref1_);

  // There is no need to append |.get()| inside static_cast - unlike the
  // const_cast and reinterpret_cast examples above, static_cast will compile
  // just fine.
  DerivedClass& d = static_cast<DerivedClass&>(my_struct.ref1_);
}

}  // namespace cast_tests

namespace ternary_operator_tests {

void foo(int x) {
  SomeClass s;
  MyStruct my_struct(s, s, s);
  SomeClass* other_ptr = nullptr;

  // To avoid the following error type:
  //     conditional expression is ambiguous; 'const raw_ptr<SomeClass>'
  //     can be converted to 'SomeClass *' and vice versa
  // we need to append |.get()| to |my_struct.ptr| below.
  //
  // Expected rewrite: ... my_struct.ptr.get() ...
  SomeClass* v = (x > 123) ? my_struct.ptr : other_ptr;

  // Rewrite in the other position.
  // Expected rewrite: ... my_struct.ptr.get() ...
  SomeClass* v2 = (x > 456) ? other_ptr : my_struct.ptr;

  // No rewrite is needed for the first, conditional argument.
  // No rewrite expected.
  int v3 = my_struct.ptr ? 123 : 456;

  // Test for 1st and 2nd arg.  Only 2nd arg should be rewritten.
  SomeClass* v4 = my_struct.ptr ? my_struct.ptr : other_ptr;
}

void foo2(int x) {
  SomeClass s;
  MyStruct my_struct(s, s, s);
  SomeClass* other_ptr = nullptr;

  // Expected rewrite: SomeClass* v = (x > 123) ? &*my_struct.ref1_ :
  // other_ptr;
  SomeClass* v = (x > 123) ? &my_struct.ref1_ : other_ptr;

  // Rewrite in the other position.
  // Expected rewrite: SomeClass* v2 = (x > 456) ? other_ptr :
  // &*my_struct.ref1_;
  SomeClass* v2 = (x > 456) ? other_ptr : &my_struct.ref1_;
}

}  // namespace ternary_operator_tests

namespace string_comparison_operator_tests {

void foo(int x) {
  SomeClass s;
  MyStruct my_struct(s, s, s);
  std::string other_str = "other";

  // No rewrite expected. (for now)
  // TODO(crbug.com/40245402) |const char| pointer fields are not supported yet.
  bool v1 = my_struct.const_char_ptr == other_str;
  bool v2 = other_str == my_struct.const_char_ptr;
  bool v3 = my_struct.const_char_ptr > other_str;
  bool v4 = other_str > my_struct.const_char_ptr;
  bool v5 = my_struct.const_char_ptr >= other_str;
  bool v6 = other_str >= my_struct.const_char_ptr;
  bool v7 = my_struct.const_char_ptr < other_str;
  bool v8 = other_str < my_struct.const_char_ptr;
  bool v9 = my_struct.const_char_ptr <= other_str;
  bool v10 = other_str <= my_struct.const_char_ptr;
  std::string v11 = my_struct.const_char_ptr + other_str;
  std::string v12 = other_str + my_struct.const_char_ptr;
}

}  // namespace string_comparison_operator_tests

namespace templated_functions {

template <typename T>
void AffectedFunction(T* t) {}

template <typename T>
void TemplatedFunction_NonTemplatedParam(SomeClass* arg, T t) {}

template <typename T>
class MyTemplate {
 public:
  template <typename U>
  MyTemplate(U* u) {}

  void AffectedMethod(T* t) {}
};

// We also want to append |.get()| for |T| parameters (i.e. not just for |T*|
// parameters).
//
// One motivating example is the following pattern from
// //components/variations/service/ui_string_overrider.cc where the type of the
// 2 arguments needs to be kept consistent:
//     const uint32_t* end = ptr_field_ + num_resources_;
//     const uint32_t* element = std::lower_bound(ptr_field_, end, hash);
template <typename T>
void AffectedNonPointerFunction(T t) {}

// base::Unretained has a template specialization that accepts `const
// raw_ptr<T>&` as an argument (since https://crrev.com/c/3283196).  Therefore
// we expect that `.get()` is *not* used when calling base::Unretained.
//
// Originally, ActivityLogDatabasePolicy::ScheduleAndForget was used as a
// motivating example - passes a raw_ptr to base::Unretained.
template <typename T>
void Unretained(T* t) {}

// AffectedFunctionWithDeepT mimics ConvertPPResourceArrayToObjects from
// //ppapi/cpp/array_output.h
template <typename T>
void AffectedFunctionWithDeepT(MyTemplate<T>* blah) {}

// StructWithPointerToTemplate is used to test AffectedFunctionWithDeepT.
// StructWithPointerToTemplate mimics ResourceArrayOutputAdapter<T>
// (and its |output_| field that will be converted to a raw_ptr)
// from //ppapi/cpp/array_output.h
template <typename T>
struct StructWithPointerToTemplate {
  MyTemplate<T>* ptr_to_template;
};

void foo() {
  SomeClass s;
  MyStruct my_struct(s, s, s);

  // Expected rewrite - appending: .get()
  AffectedFunction(my_struct.ptr);

  // Expected rewrite - appending: .get()
  MyTemplate<SomeClass> mt(my_struct.ptr);
  // Expected rewrite - appending: .get()
  mt.AffectedMethod(my_struct.ptr);

  // No rewrite expected.
  TemplatedFunction_NonTemplatedParam(my_struct.ptr, 123);

  // Expected rewrite - appending: .get()
  AffectedNonPointerFunction(my_struct.ptr);

  // Expected rewrite - appending: .get()
  StructWithPointerToTemplate<SomeClass> swptt;
  AffectedFunctionWithDeepT(swptt.ptr_to_template);

  // No rewrite expected - T& parameter.
  std::swap(my_struct.ptr, my_struct.ptr2);
  std::tie(my_struct.ptr, my_struct.ptr2) = std::make_pair(nullptr, nullptr);

  // No rewrite expected - functions named "Unretained" are excluded (they have
  // been manually modified to also provide a template specialization that
  // accepts `const raw_ptr<T>&` as an argument).
  Unretained(my_struct.ptr);
}

}  // namespace templated_functions

namespace templated_functions_raw_ref_tests {

template <typename T>
void AffectedFunction(T& t) {}

template <typename T>
void TemplatedFunction_NonTemplatedParam(SomeClass& arg, T t) {}

template <typename T>
class MyTemplate {
 public:
  template <typename U>
  MyTemplate(U& u) {}

  void AffectedMethod(T& t) {}
};

template <typename T>
void AffectedNonPointerFunction(T t) {}

// AffectedFunctionWithDeepT mimics ConvertPPResourceArrayToObjects from
// //ppapi/cpp/array_output.h
template <typename T>
void AffectedFunctionWithDeepT(MyTemplate<T>& blah) {}

// StructWithPointerToTemplate is used to test AffectedFunctionWithDeepT.
// StructWithPointerToTemplate mimics ResourceArrayOutputAdapter<T>
// (and its |output_| field that will be converted to a raw_ref)
// from //ppapi/cpp/array_output.h
template <typename T>
struct StructWithPointerToTemplate {
  StructWithPointerToTemplate(MyTemplate<T>& ref) : ref_to_template(ref) {}
  MyTemplate<T>& ref_to_template;
};

void foo() {
  SomeClass s;
  MyStruct my_struct(s, s, s);

  // Expected rewrite: AffectedFunction(*my_struct.ref1_);
  AffectedFunction(my_struct.ref1_);

  // Expected rewrite: MyTemplate<SomeClass> mt(*my_struct.ref1_);
  MyTemplate<SomeClass> mt(my_struct.ref1_);
  // Expected rewrite: mt.AffectedMethod(*my_struct.ref1_);
  mt.AffectedMethod(my_struct.ref1_);

  // Expected rewrite: TemplatedFunction_NonTemplatedParam(*my_struct.ref1_,
  // 123)
  TemplatedFunction_NonTemplatedParam(my_struct.ref1_, 123);

  // Expected rewrite: AffectedNonPointerFunction(*my_struct.ref1_);
  AffectedNonPointerFunction(my_struct.ref1_);

  MyTemplate<SomeClass> my_template(s);
  StructWithPointerToTemplate<SomeClass> swptt(my_template);
  // Expected rewrite: AffectedFunctionWithDeepT(*swptt.ref_to_template);
  AffectedFunctionWithDeepT(swptt.ref_to_template);

  // Expected rewrite: std::swap(*my_struct.ref1_, *my_struct.ref2_)
  std::swap(my_struct.ref1_, my_struct.ref2_);
  std::tie(my_struct.ref1_, my_struct.ref2_) = std::make_pair(s, s);
}

}  // namespace templated_functions_raw_ref_tests

namespace implicit_constructors {

// Based on //base/strings/string_piece.h:
template <typename CharT>
class BasicStringPiece;
typedef BasicStringPiece<char> StringPiece;
// Based on //base/strings/string_piece.h:
template <typename CharT>
class BasicStringPiece {
 public:
  constexpr BasicStringPiece(const char* str) {}
};
// Test case:
void FunctionTakingBasicStringPiece(StringPiece arg) {}
void FunctionTakingBasicStringPieceRef(const StringPiece& arg) {}

class ClassWithImplicitConstructor {
 public:
  ClassWithImplicitConstructor(SomeClass* blah) {}
};
void FunctionTakingArgWithImplicitConstructor(
    ClassWithImplicitConstructor arg) {}

void foo() {
  SomeClass s;
  MyStruct my_struct(s, s, s);

  // No rewrite expected. (for now)
  // TODO(crbug.com/40245402) |const char| pointer fields are not supported yet.
  FunctionTakingBasicStringPiece(my_struct.const_char_ptr);
  FunctionTakingBasicStringPieceRef(my_struct.const_char_ptr);

  // No rewrite expected.
  FunctionTakingBasicStringPiece(StringPiece(my_struct.const_char_ptr));
  FunctionTakingBasicStringPieceRef(StringPiece(my_struct.const_char_ptr));

  // Expected rewrite - appending: .get().  This is the same scenario as with
  // StringPiece above (except that no templates are present here).
  FunctionTakingArgWithImplicitConstructor(my_struct.ptr);
}

}  // namespace implicit_constructors

namespace implicit_constructors_raw_ref_tests {

// Based on //base/strings/string_piece.h:
template <typename CharT>
class BasicStringPiece;
typedef BasicStringPiece<char> StringPiece;
// Based on //base/strings/string_piece.h:
template <typename CharT>
class BasicStringPiece {
 public:
  constexpr BasicStringPiece(const char* str) {}
};
// Test case:
void FunctionTakingBasicStringPiece(StringPiece arg) {}
void FunctionTakingBasicStringPieceRef(const StringPiece& arg) {}

class ClassWithImplicitConstructor {
 public:
  ClassWithImplicitConstructor(SomeClass& blah) {}
};
void FunctionTakingArgWithImplicitConstructor(
    ClassWithImplicitConstructor arg) {}

void foo() {
  SomeClass s;
  MyStruct my_struct(s, s, s);
  // Expected rewrite:
  // FunctionTakingArgWithImplicitConstructor(*my_struct.ref1_);
  FunctionTakingArgWithImplicitConstructor(my_struct.ref1_);
}

}  // namespace implicit_constructors_raw_ref_tests

namespace affected_implicit_template_specialization {

template <typename T, typename T2>
struct MyTemplate {
  T* t_ptr;
  T2* t2_ptr;

  struct NestedStruct {
    SomeClass* nested_ptr_field;
    T* nested_t_ptr_field;
  };
  NestedStruct nested_struct_field;
};

template <typename T3>
struct MyTemplate<SomeClass, T3> {
  SomeClass* some_ptr;
  T3* t3_ptr;
};

// The example that forces explicit |isAnonymousStructOrUnion| checks in
// the implementation of GetExplicitDecl.  The example is based on
// buildtools/third_party/libc++/trunk/include/string.
template <typename T>
struct MyStringTemplate {
  struct NestedStruct {
    union {
      long l;
      short s;
      T* t_ptr;
      int* i_ptr;
    };  // Unnamed / anonymous union *field*.

    struct {
      long l2;
      short s2;
      T* t_ptr2;
      int* i_ptr2;
    };  // Unnamed / anonymous struct *field*.
  };
  NestedStruct s;
};

void MyPrintf(const char* fmt, ...) {}

void foo() {
  // |s.t_ptr| comes from implicit template specialization (which needs to be
  // skipped for rewriting, but should be included for appending |.get()|).
  //
  // Expected rewrite: MyPrintf("%p", s.t_ptr.get());
  MyTemplate<int, int> s;
  MyPrintf("%p", s.t_ptr);

  // |s.some_ptr| and |s.t2_ptr| come from implicit template specialization or a
  // partial template specialization.
  //
  // Expected rewrite: MyPrintf("%p", s.some_ptr.get(), s.t3_ptr.get());
  MyTemplate<SomeClass, int> s2;
  MyPrintf("%p %p", s2.some_ptr, s2.t3_ptr);

  // Nested structs require extra care when trying to look up the non-implicit
  // field definition.  Expected rewrite: adding |.get()| suffix.
  MyPrintf("%p", s.nested_struct_field.nested_ptr_field);
  MyPrintf("%p", s.nested_struct_field.nested_t_ptr_field);

  // Lines below are added mainly to Force implicit specialization of
  // MyStringTemplate (to force explicit |isAnonymousStructOrUnion| checks in
  // the rewriter).  Still, the expected rewrite is: appending |.get()| to the
  // printf arg.
  MyStringTemplate<void> mst;
  MyPrintf("%p %p", mst.s.t_ptr, mst.s.t_ptr2);
}

}  // namespace affected_implicit_template_specialization

namespace affected_implicit_template_specialization_raw_ref_tests {

template <typename T, typename T2>
struct MyTemplate {
  T& t_ref;
  T2& t2_ref;

  struct NestedStruct {
    SomeClass& nested_ref_field;
    T& nested_t_ref_field;
  };
  NestedStruct nested_struct_field;
};

template <typename T3>
struct MyTemplate<SomeClass, T3> {
  SomeClass& some_ptr;
  T3& t3_ptr;
};
}  // namespace affected_implicit_template_specialization_raw_ref_tests

// The test scenario below is based on an example encountered in
// //cc/layers/picture_layer_impl_unittest.cc:
//   auto* shared_quad_state = render_pass->quad_list.begin()->shared_quad_state
// In this example, the AST looks like this:
//  `-DeclStmt
//    `-VarDecl shared_quad_state 'const SharedQuadState *' cinit
//      `-ExprWithCleanups 'const SharedQuadState *'
//        `-ImplicitCastExpr 'const SharedQuadState *' <LValueToRValue>
//          `-MemberExpr 'const SharedQuadState *const' lvalue ->shared...state
//            `-.....
// The rewriter needs to ignore the implicit ExprWithCleanups and
// ImplicitCastExpr nodes in order to find the MemberExpr.  If this is
// implemented incorrectly, then the rewriter won't append |.get()| to fix the
// |auto*| initialization.
namespace more_implicit_ast_nodes_trouble {

template <class BaseElementType>
struct ListContainer {
  struct ConstIterator {
    const BaseElementType* operator->() const { return nullptr; }
  };

  ConstIterator begin() const { return ConstIterator(); }
};

class SharedQuadState;

struct DrawQuad {
  const SharedQuadState* shared_quad_state;
};

struct RenderPass {
  using QuadList = ListContainer<DrawQuad>;
  QuadList quad_list;
};

void foo() {
  RenderPass* render_pass = nullptr;
  auto* shared_quad_state = render_pass->quad_list.begin()->shared_quad_state;
}

}  // namespace more_implicit_ast_nodes_trouble
