普通文本  |  110行  |  3.5 KB

// Copyright 2016 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 <memory>

#include "values.h"

#define true true

base::ListValue* ReturnsRawPtr() {
  return nullptr;
}

std::unique_ptr<base::Value> ReturnsUniquePtr() {
  return nullptr;
}

// The joy of raw pointers.
void DoesItTakeOwnership(base::Value*) {}

struct Thing {
  std::unique_ptr<base::Value> ToValue() { return nullptr; }
};

void F() {
  base::ListValue list;
  list.AppendBoolean(1 == 0);
  list.AppendBoolean(true);
  list.AppendInteger(static_cast<unsigned char>(1.0));
  list.AppendDouble(double{3});
  list.AppendString("abc");

  list.Append(ReturnsUniquePtr());
  Thing thing;
  list.Append(thing.ToValue());
  std::unique_ptr<base::Value> unique_ptr_var;
  list.Append(std::move(unique_ptr_var));
}

void G(base::Value* input) {
  base::ListValue list;

  std::unique_ptr<base::ListValue> local(new base::ListValue());
  // Not rewritten, since it often makes more sense to change the function
  // prototype.
  local->Append(input);
  // Should be rewritten: it will only be moved after it's no longer referenced.
  list.Append(std::move(local));

  // Not rewritten, since it would be used after it's moved. In theory, we could
  // automatically handle this too, but the risk of accidentally breaking
  // something is much higher.
  base::ListValue* clever_list = new base::ListValue;
  list.Append(clever_list);
  clever_list->AppendInteger(2);

  // Not rewritten, since it often makes more sense to change the function
  // prototype.
  base::Value* returned_value = ReturnsRawPtr();
  list.Append(returned_value);

  // Should be rewritten. The reassignment should be transformed into
  // .reset().
  std::unique_ptr<base::ListValue> reused_list(new base::ListValue);
  reused_list->AppendInteger(1);
  list.Append(std::move(reused_list));
  reused_list.reset(new base::ListValue);
  reused_list->AppendInteger(3);
  list.Append(std::move(reused_list));

  // This shouldn't be rewritten, since the reassignment is the return
  // value of a function.
  base::ListValue* reused_list_2 = new base::ListValue;
  reused_list_2->AppendInteger(4);
  list.Append(reused_list_2);
  reused_list_2 = ReturnsRawPtr();
  reused_list_2->AppendInteger(5);
  list.Append(reused_list_2);

  // auto should be expanded to a std::unique_ptr containing the deduced type.
  std::unique_ptr<class base::ListValue> auto_list(new base::ListValue);
  auto_list->AppendInteger(6);
  list.Append(std::move(auto_list));

  std::unique_ptr<class base::ListValue> auto_list_2(new base::ListValue);
  auto_list_2->AppendInteger(7);
  list.Append(std::move(auto_list_2));

  // Shouldn't be rewritten: a raw pointer is passed to a function which may or
  // may not take ownership.
  base::ListValue* maybe_owned_list = new base::ListValue;
  DoesItTakeOwnership(maybe_owned_list);
  list.Append(maybe_owned_list);

  // Should be rewritten, even though it doesn't have an initializer.
  std::unique_ptr<base::ListValue> list_with_no_initializer;
  list_with_no_initializer.reset(new base::ListValue);
  list.Append(std::move(list_with_no_initializer));

  // Make sure C++98 style initialization is correctly handled.
  std::unique_ptr<base::ListValue> cxx98_list(new base::ListValue);
  list.Append(std::move(cxx98_list));

  // C++11 style syntax currently causes the tool to bail out: this is banned in
  // Chromium style anyway.
  base::ListValue* cxx11_list{new base::ListValue};
  list.Append(cxx11_list);
}