// 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 <cstdint>
#include <map>
#include <optional>
#include <vector>
#include "base/containers/span.h"
class SomeClass;
class MyClass {
MyClass(SomeClass& s) : raw_ref_field(s) {}
// Expected rewrite: raw_ptr<SomeClass> raw_ptr_field;
SomeClass* raw_ptr_field;
// Expected rewrite: const raw_ref<SomeClass> raw_ref_field;
SomeClass& raw_ref_field;
// No rewrite expected.
int int_field;
// Expected rewrite: base::raw_span<SomeClass> span_field;
base::span<SomeClass> span_field;
// Expected rewrite: base::raw_span<SomeClass> span_field;
std::vector<base::span<SomeClass>> container_of_span_field;
// Expected rewrite:
// std::vector<std::optional<base::raw_span<SomeClass>>>
std::vector<std::optional<base::span<SomeClass>>>
container_of_optional_span_field;
// Expected rewrite: base::raw_span<SomeClass> span_field;
base::span<SomeClass> base_span_field;
// No rewrite expected.
base::raw_span<SomeClass> base_raw_span_field;
// Expected rewrite: std::optional<base::raw_span<SomeClass>>
// optional_span_field;
std::optional<base::span<SomeClass>> optional_span_field;
// Expected rewrite: std::map<int, base::raw_span<SomeClass>> map_span_field1;
std::map<int, base::span<SomeClass>> map_span_field1;
// Expected rewrite: std::map<base::raw_span<SomeClass>, int> map_span_field2;
std::map<base::span<SomeClass>, int> map_span_field2;
// Expected rewrite: std::map<base::raw_span<SomeClass>,
// base::raw_span<SomeClass>> map_span_field3;
std::map<base::span<SomeClass>, base::span<SomeClass>> map_span_field3;
// Expected rewrite:
// std::map<base::span<const char>, base::raw_span<SomeClass>>
std::map<base::span<const char>, base::span<SomeClass>> map_span_field4;
// Expected rewrite:
// std::map<base::raw_span<SomeClass>, base::span<const char>>
std::map<base::span<SomeClass>, base::span<const char>> map_span_field5;
// These fields are not expected to be rewritten.
// Commented out due to presubmit failures (char8_t is not allowed in chromium
// code yet).
// base::span<const char8_t> const_char8_span;
// std::optional<base::span<const char8_t>> optional_const_char8_span;
// std::vector<base::span<const char8_t>> vector_const_char8_span;
// std::vector<std::optional<base::span<const char8_t>>>
// vector_optional_const_char8_span;
// No rewrite expected for the following fields;
base::span<const char> const_char_span;
base::span<const wchar_t> const_wchar_span;
base::span<const char16_t> const_char16_span;
base::span<const char32_t> const_char32_span;
std::optional<base::span<const char>> optional_const_char_span;
std::optional<base::span<const wchar_t>> optional_const_wchar_span;
std::optional<base::span<const char16_t>> optional_const_char16_span;
std::optional<base::span<const char32_t>> optional_const_char32_span;
std::vector<base::span<const char>> vector_const_char_span;
std::vector<base::span<const wchar_t>> vector_const_wchar_span;
std::vector<base::span<const char16_t>> vector_const_char16_span;
std::vector<base::span<const char>> vector_const_char32_span;
std::vector<std::optional<base::span<const char>>>
vector_optional_const_char_span;
std::vector<std::optional<base::span<const wchar_t>>>
vector_optional_const_wchar_span;
std::vector<std::optional<base::span<const char16_t>>>
vector_optional_const_char16_span;
std::vector<std::optional<base::span<const char32_t>>>
vector_optional_const_char32_span;
// All of the following fields are expected to be rewritten:
// Expected rewrite: base::raw_span<const type>
base::span<const uint8_t> const_uint8_span;
base::span<const int8_t> const_int8_span;
base::span<const uint16_t> const_uint16_span;
base::span<const int16_t> const_int16_span;
base::span<const uint32_t> const_uint32_span;
base::span<const int32_t> const_int32_span;
// All of the following fields are expected to be rewritten:
// Expected rewrite: std::optional<base::raw_span<const type>>
std::optional<base::span<const uint8_t>> optional_const_uint8_span;
std::optional<base::span<const int8_t>> optional_const_int8_span;
std::optional<base::span<const uint16_t>> optional_const_uint16_span;
std::optional<base::span<const int16_t>> optional_const_int16_span;
std::optional<base::span<const uint32_t>> optional_const_uint32_span;
std::optional<base::span<const int32_t>> optional_const_int32_span;
// All of the following fields are expected to be rewritten:
// Expected rewrite:
// std::vector<base::raw_span<const type>>
std::vector<base::span<const uint8_t>> vector_const_uint8_span;
std::vector<base::span<const int8_t>> vector_const_int8_span;
std::vector<base::span<const uint16_t>> vector_const_uint16_span;
std::vector<base::span<const int16_t>> vector_const_int16_span;
std::vector<base::span<const uint32_t>> vector_const_uint32_span;
std::vector<base::span<const int32_t>> vector_const_int32_span;
// All of the following fields are expected to be rewritten:
// Expected rewrite:
// std::vector<std::optional<base::raw_span<const type>>>
std::vector<std::optional<base::span<const uint8_t>>>
vector_optional_const_uint8_span;
std::vector<std::optional<base::span<const int8_t>>>
vector_optional_const_int8_span;
std::vector<std::optional<base::span<const uint16_t>>>
vector_optional_const_uint16_span;
std::vector<std::optional<base::span<const int16_t>>>
vector_optional_const_int16_span;
std::vector<std::optional<base::span<const uint32_t>>>
vector_optional_const_uint32_span;
std::vector<std::optional<base::span<const int32_t>>>
vector_optional_const_int32_span;
};
struct MyStruct {
MyStruct(SomeClass& s1, SomeClass& s2)
: raw_ref_field(s1), raw_ref_field2(s2) {}
// Expected rewrite: raw_ptr<SomeClass> raw_ptr_field;
SomeClass* raw_ptr_field;
// Expected rewrite: const raw_ref<SomeClass> raw_ref_field;
SomeClass& raw_ref_field;
// No rewrite expected.
int int_field;
// "*" next to the field name. This is non-standard formatting, so
// "clang-format off" is used to make sure |git cl format| won't change this
// testcase.
//
// Expected rewrite: raw_ptr<SomeClass> raw_ptr_field;
// clang-format off
SomeClass *raw_ptr_field2;
// clang-format on
// "&" next to the field name. This is non-standard formatting, so
// "clang-format off" is used to make sure |git cl format| won't change this
// testcase.
//
// Expected rewrite: const raw_ref<SomeClass> raw_ref_field;
// clang-format off
SomeClass &raw_ref_field2;
// clang-format on
};
template <typename T>
class MyTemplate {
MyTemplate(T& t) : raw_ref_field(t) {}
// Expected rewrite: raw_ptr<T> raw_ptr_field;
T* raw_ptr_field;
// Expected rewrite: const raw_ref<T> raw_ref_field;
T& raw_ref_field;
// No rewrite expected.
int int_field;
// Expected rewrite: base::raw_span<T> span_field;
base::span<T> span_field;
// Expected rewrite: std::vector<base::raw_span<T>> container_of_span_field;
std::vector<base::span<T>> container_of_span_field;
// Expected rewrite: std::optional<base::raw_span<T>> optional_span_field;
std::optional<base::span<T>> optional_span_field;
// Expected rewrite: std::optional<base::raw_span<T>> optional_span_field;
std::optional<base::span<int>> optional_int_span_field;
// Expected rewrite: std::map<int, base::raw_span<T>> map_span_field1;
std::map<int, base::span<T>> map_span_field1;
};
// The field below won't compile without the |typename| keyword (because
// at this point we don't know if MaybeProvidesType<T>::Type is a type,
// value or something else). Let's see if the rewriter will preserve
// preserve the |typename| keyword.
template <typename T>
struct MaybeProvidesType;
template <typename T>
struct DependentNameTest {
// Expected rewrite: raw_ptr<typename MaybeProvidesType<T>::Type> field;
typename MaybeProvidesType<T>::Type* field;
// Expected rewrite: const raw_ref<typename MaybeProvidesType<T>::Type>
// field2;
typename MaybeProvidesType<T>::Type& field2;
// Expected rewrite: base::raw_ptr<typename MaybeProvidesType<T>::Type>
// span_field;
base::span<typename MaybeProvidesType<T>::Type> span_field;
// Expected rewrite: std::vector<baes::raw_span<typename
// MaybeProvidesType<T>::Type>> container_of_span_field;
std::vector<base::span<typename MaybeProvidesType<T>::Type>>
container_of_span_field;
// Expected rewrite: std::optional<base::raw_span<typename
// MaybeProvidesType<T>::Type>> optional_span_field;
std::optional<base::span<typename MaybeProvidesType<T>::Type>>
optional_span_field;
// Expected rewrite: std::map<int,
// base::raw_span<typenameMaybeProvidesType<T>::Type>> map_span_field;
std::map<int, base::span<typename MaybeProvidesType<T>::Type>> map_span_field;
};
namespace base {
using spancontainedtype = int;
struct S {
// Expected rewrite:
// raw_span<spancontainedtype> member;
span<spancontainedtype> member;
};
} // namespace base