// 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.
//
// Changes Blink-style names to Chrome-style names. Currently transforms:
//   fields:
//     int m_operationCount => int operation_count_
//   variables (including parameters):
//     int mySuperVariable => int my_super_variable
//   constants:
//     const int maxThings => const int kMaxThings
//   free functions and methods:
//     void doThisThenThat() => void DoThisAndThat()

#include <assert.h>
#include <algorithm>
#include <memory>
#include <set>
#include <string>

#include "clang/AST/ASTContext.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/ASTMatchers/ASTMatchers.h"
#include "clang/ASTMatchers/ASTMatchersMacros.h"
#include "clang/Basic/CharInfo.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendActions.h"
#include "clang/Lex/Lexer.h"
#include "clang/Lex/MacroArgs.h"
#include "clang/Lex/PPCallbacks.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Tooling/CommonOptionsParser.h"
#include "clang/Tooling/Refactoring.h"
#include "clang/Tooling/Tooling.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorOr.h"
#include "llvm/Support/LineIterator.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/TargetSelect.h"

#include "EditTracker.h"

using namespace clang::ast_matchers;
using clang::tooling::CommonOptionsParser;
using clang::tooling::Replacement;
using llvm::StringRef;

namespace {

const char kBlinkFieldPrefix[] = "m_";
const char kBlinkStaticMemberPrefix[] = "s_";
const char kGMockMethodNamePrefix[] = "gmock_";
const char kMethodBlocklistParamName[] = "method-blocklist";

std::set<clang::SourceLocation>& GetRewrittenLocs() {
  static auto& locations = *new std::set<clang::SourceLocation>();
  return locations;
}

template <typename MatcherType, typename NodeType>
bool IsMatching(const MatcherType& matcher,
                const NodeType& node,
                clang::ASTContext& context) {
  return !match(matcher, node, context).empty();
}

const clang::ast_matchers::internal::
    VariadicDynCastAllOfMatcher<clang::Expr, clang::UnresolvedMemberExpr>
        unresolvedMemberExpr;

const clang::ast_matchers::internal::
    VariadicDynCastAllOfMatcher<clang::Expr, clang::DependentScopeDeclRefExpr>
        dependentScopeDeclRefExpr;

const clang::ast_matchers::internal::
    VariadicDynCastAllOfMatcher<clang::Expr, clang::CXXDependentScopeMemberExpr>
        cxxDependentScopeMemberExpr;

AST_MATCHER(clang::FunctionDecl, isOverloadedOperator) {
  return Node.isOverloadedOperator();
}

AST_MATCHER(clang::CXXMethodDecl, isInstanceMethod) {
  return Node.isInstance();
}

AST_MATCHER_P(clang::FunctionTemplateDecl,
              templatedDecl,
              clang::ast_matchers::internal::Matcher<clang::FunctionDecl>,
              InnerMatcher) {
  return InnerMatcher.matches(*Node.getTemplatedDecl(), Finder, Builder);
}

AST_MATCHER_P(clang::Decl,
              hasCanonicalDecl,
              clang::ast_matchers::internal::Matcher<clang::Decl>,
              InnerMatcher) {
  return InnerMatcher.matches(*Node.getCanonicalDecl(), Finder, Builder);
}

// Matches a CXXMethodDecl of a method declared via MOCK_METHODx macro if such
// method mocks a method matched by the InnerMatcher.  For example if "foo"
// matcher matches "interfaceMethod", then mocksMethod(foo()) will match
// "gmock_interfaceMethod" declared by MOCK_METHOD_x(interfaceMethod).
AST_MATCHER_P(clang::CXXMethodDecl,
              mocksMethod,
              clang::ast_matchers::internal::Matcher<clang::CXXMethodDecl>,
              InnerMatcher) {
  if (!Node.getDeclName().isIdentifier())
    return false;

  llvm::StringRef method_name = Node.getName();
  if (!method_name.startswith(kGMockMethodNamePrefix))
    return false;

  llvm::StringRef mocked_method_name =
      method_name.substr(strlen(kGMockMethodNamePrefix));
  for (const auto& potentially_mocked_method : Node.getParent()->methods()) {
    clang::DeclarationName decl_name = potentially_mocked_method->getDeclName();
    if (!decl_name.isIdentifier() ||
        potentially_mocked_method->getName() != mocked_method_name)
      continue;
    if (potentially_mocked_method->getNumParams() != Node.getNumParams())
      continue;

    if (InnerMatcher.matches(*potentially_mocked_method, Finder, Builder))
      return true;
  }

  return false;
}

class MethodBlocklist {
 public:
  explicit MethodBlocklist(const std::string& filepath) {
    if (!filepath.empty())
      ParseInputFile(filepath);
  }

  bool Contains(const clang::FunctionDecl& method) const {
    if (!method.getDeclName().isIdentifier())
      return false;

    auto it = method_to_classes_.find(method.getName());
    if (it == method_to_classes_.end())
      return false;

    // |method_context| is either
    // 1) a CXXRecordDecl (i.e. blink::Document) or
    // 2) a NamespaceDecl (i.e. blink::DOMWindowTimers).
    const clang::NamedDecl* method_context =
        clang::dyn_cast<clang::NamedDecl>(method.getDeclContext());
    if (!method_context)
      return false;
    if (!method_context->getDeclName().isIdentifier())
      return false;

    const llvm::StringSet<>& classes = it->second;
    auto it2 = classes.find(method_context->getName());
    if (it2 == classes.end())
      return false;

    // No need to verify here that |actual_class| is in the |blink| namespace -
    // this will be done by other matchers elsewhere.

    // TODO(lukasza): Do we need to consider return type and/or param types?

    // TODO(lukasza): Do we need to consider param count?

    return true;
  }

 private:
  // Each line is expected to have the following format:
  // <class name>:::<method name>:::<number of arguments>
  void ParseInputFile(const std::string& filepath) {
    llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> file_or_err =
        llvm::MemoryBuffer::getFile(filepath);
    if (std::error_code err = file_or_err.getError()) {
      llvm::errs() << "ERROR: Cannot open the file specified in --"
                   << kMethodBlocklistParamName << " argument: " << filepath
                   << ": " << err.message() << "\n";
      assert(false);
      return;
    }

    llvm::line_iterator it(**file_or_err, true /* SkipBlanks */, '#');
    for (; !it.is_at_eof(); ++it) {
      llvm::StringRef line = it->trim();
      if (line.empty())
        continue;

      // Split the line into ':::'-delimited parts.
      const size_t kExpectedNumberOfParts = 3;
      llvm::SmallVector<llvm::StringRef, kExpectedNumberOfParts> parts;
      line.split(parts, ":::");
      if (parts.size() != kExpectedNumberOfParts) {
        llvm::errs() << "ERROR: Parsing error - expected "
                     << kExpectedNumberOfParts
                     << " ':::'-delimited parts: " << filepath << ":"
                     << it.line_number() << ": " << line << "\n";
        assert(false);
        continue;
      }

      // Parse individual parts.
      llvm::StringRef class_name = parts[0];
      llvm::StringRef method_name = parts[1];
      // ignoring parts[2] - the (not so trustworthy) number of parameters.

      // Store the new entry.
      method_to_classes_[method_name].insert(class_name);
    }
  }

  // Stores methods to blacklist in a map:
  // method name -> class name -> set of all allowed numbers of arguments.
  llvm::StringMap<llvm::StringSet<>> method_to_classes_;
};

AST_MATCHER_P(clang::FunctionDecl,
              isBlocklistedMethod,
              MethodBlocklist,
              Blocklist) {
  return Blocklist.Contains(Node);
}

// If |InnerMatcher| matches |top|, then the returned matcher will match:
// - |top::function|
// - |top::Class::method|
// - |top::internal::Class::method|
AST_MATCHER_P(
    clang::NestedNameSpecifier,
    hasTopLevelPrefix,
    clang::ast_matchers::internal::Matcher<clang::NestedNameSpecifier>,
    InnerMatcher) {
  const clang::NestedNameSpecifier* NodeToMatch = &Node;
  while (NodeToMatch->getPrefix())
    NodeToMatch = NodeToMatch->getPrefix();
  return InnerMatcher.matches(*NodeToMatch, Finder, Builder);
}

// This will narrow CXXCtorInitializers down for both FieldDecls and
// IndirectFieldDecls (ie. anonymous unions and such). In both cases
// getAnyMember() will return a FieldDecl which we can match against.
AST_MATCHER_P(clang::CXXCtorInitializer,
              forAnyField,
              clang::ast_matchers::internal::Matcher<clang::FieldDecl>,
              InnerMatcher) {
  const clang::FieldDecl* NodeAsDecl = Node.getAnyMember();
  return (NodeAsDecl != nullptr &&
          InnerMatcher.matches(*NodeAsDecl, Finder, Builder));
}

// Matches if all the overloads in the lookup set match the provided matcher.
AST_MATCHER_P(clang::OverloadExpr,
              allOverloadsMatch,
              clang::ast_matchers::internal::Matcher<clang::NamedDecl>,
              InnerMatcher) {
  if (Node.getNumDecls() == 0)
    return false;

  for (clang::NamedDecl* decl : Node.decls()) {
    if (!InnerMatcher.matches(*decl, Finder, Builder))
      return false;
  }
  return true;
}

void PrintForDiagnostics(clang::raw_ostream& os,
                         const clang::FunctionDecl& decl) {
  decl.getLocStart().print(os, decl.getASTContext().getSourceManager());
  os << ": ";
  decl.getNameForDiagnostic(os, decl.getASTContext().getPrintingPolicy(), true);
}

template <typename T>
bool MatchAllOverriddenMethods(
    const clang::CXXMethodDecl& decl,
    T&& inner_matcher,
    clang::ast_matchers::internal::ASTMatchFinder* finder,
    clang::ast_matchers::internal::BoundNodesTreeBuilder* builder) {
  bool override_matches = false;
  bool override_not_matches = false;

  for (auto it = decl.begin_overridden_methods();
       it != decl.end_overridden_methods(); ++it) {
    if (MatchAllOverriddenMethods(**it, inner_matcher, finder, builder))
      override_matches = true;
    else
      override_not_matches = true;
  }

  // If this fires we have a class overriding a method that matches, and a
  // method that does not match the inner matcher. In that case we will match
  // one ancestor method but not the other. If we rename one of the and not the
  // other it will break what this class overrides, disconnecting it from the
  // one we did not rename which creates a behaviour change. So assert and
  // demand the user to fix the code first (or add the method to our
  // blacklist T_T).
  if (override_matches && override_not_matches) {
    // blink::InternalSettings::trace method overrides
    // 1) blink::InternalSettingsGenerated::trace
    //    (won't be renamed because it is in generated code)
    // 2) blink::Supplement<blink::Page>::trace
    //    (will be renamed).
    // It is safe to rename blink::InternalSettings::trace, because
    // both 1 and 2 will both be renamed (#1 via manual changes of the code
    // generator for DOM bindings and #2 via the clang tool).
    auto internal_settings_class_decl = cxxRecordDecl(
        hasName("InternalSettings"),
        hasParent(namespaceDecl(hasName("blink"),
                                hasParent(translationUnitDecl()))));
    auto is_method_safe_to_rename = cxxMethodDecl(
        hasName("trace"),
        anyOf(hasParent(internal_settings_class_decl),  // in .h file
              has(nestedNameSpecifier(specifiesType(    // in .cpp file
                  hasDeclaration(internal_settings_class_decl))))));
    if (IsMatching(is_method_safe_to_rename, decl, decl.getASTContext()))
      return true;

    // For previously unknown conflicts, error out and require a human to
    // analyse the problem (rather than falling back to a potentially unsafe /
    // code semantics changing rename).
    llvm::errs() << "ERROR: ";
    PrintForDiagnostics(llvm::errs(), decl);
    llvm::errs() << " method overrides "
                 << "some virtual methods that will be automatically renamed "
                 << "and some that won't be renamed.";
    llvm::errs() << "\n";
    for (auto it = decl.begin_overridden_methods();
         it != decl.end_overridden_methods(); ++it) {
      if (MatchAllOverriddenMethods(**it, inner_matcher, finder, builder))
        llvm::errs() << "Overriden method that will be renamed: ";
      else
        llvm::errs() << "Overriden method that will not be renamed: ";
      PrintForDiagnostics(llvm::errs(), **it);
      llvm::errs() << "\n";
    }
    llvm::errs() << "\n";
    assert(false);
  }

  // If the method overrides something that doesn't match, so the method itself
  // doesn't match.
  if (override_not_matches)
    return false;

  // If the method overrides something that matches, so the method ifself
  // matches.
  if (override_matches)
    return true;

  return inner_matcher.matches(decl, finder, builder);
}

AST_MATCHER_P(clang::CXXMethodDecl,
              includeAllOverriddenMethods,
              clang::ast_matchers::internal::Matcher<clang::CXXMethodDecl>,
              InnerMatcher) {
  return MatchAllOverriddenMethods(Node, InnerMatcher, Finder, Builder);
}

// Matches |T::m| and/or |x->T::m| and/or |x->m| CXXDependentScopeMemberExpr
// if member |m| comes from a type that matches the InnerMatcher.
AST_MATCHER_P(clang::CXXDependentScopeMemberExpr,
              hasMemberFromType,
              clang::ast_matchers::internal::Matcher<clang::QualType>,
              InnerMatcher) {
  // Given |T::m| and/or |x->T::m| and/or |x->m| ...
  if (clang::NestedNameSpecifier* nestedNameSpecifier = Node.getQualifier()) {
    // ... if |T| is present, then InnerMatcher has to match |T|.
    clang::QualType qualType(nestedNameSpecifier->getAsType(), 0);
    return InnerMatcher.matches(qualType, Finder, Builder);
  } else {
    // ... if there is no |T|, then InnerMatcher has to match the type of |x|.
    clang::Expr* base_expr = Node.isImplicitAccess() ? nullptr : Node.getBase();
    return base_expr &&
           InnerMatcher.matches(base_expr->getType(), Finder, Builder);
  }
}

// Matches |const Class<T>&| QualType if InnerMatcher matches |Class<T>|.
AST_MATCHER_P(clang::QualType,
              hasBaseType,
              clang::ast_matchers::internal::Matcher<clang::Type>,
              InnerMatcher) {
  const clang::Type* type = Node.getTypePtrOrNull();
  return type && InnerMatcher.matches(*type, Finder, Builder);
}

bool IsMethodOverrideOf(const clang::CXXMethodDecl& decl,
                        const char* class_name) {
  if (decl.getParent()->getQualifiedNameAsString() == class_name)
    return true;
  for (auto it = decl.begin_overridden_methods();
       it != decl.end_overridden_methods(); ++it) {
    if (IsMethodOverrideOf(**it, class_name))
      return true;
  }
  return false;
}

bool IsBlacklistedFunctionName(llvm::StringRef name) {
  // https://crbug.com/672902: Method names with an underscore are typically
  // mimicked after std library / are typically not originating from Blink.
  // Do not rewrite such names (like push_back, emplace_back, etc.).
  if (name.find('_') != llvm::StringRef::npos)
    return true;

  return false;
}

bool IsBlacklistedFreeFunctionName(llvm::StringRef name) {
  // swap() functions should match the signature of std::swap for ADL tricks.
  return name == "swap";
}

bool IsBlacklistedInstanceMethodName(llvm::StringRef name) {
  static const char* kBlacklistedNames[] = {
      // We should avoid renaming the method names listed below, because
      // 1. They are used in templated code (e.g. in <algorithms>)
      // 2. They (begin+end) are used in range-based for syntax sugar
      //    - for (auto x : foo) { ... }  // <- foo.begin() will be called.
      "begin", "end", "rbegin", "rend", "lock", "unlock", "try_lock",

      // https://crbug.com/672902: Should not rewrite names that mimick methods
      // from std library.
      "at", "back", "empty", "erase", "front", "insert", "length", "size",
  };
  for (const auto& b : kBlacklistedNames) {
    if (name == b)
      return true;
  }
  return false;
}

bool IsBlacklistedMethodName(llvm::StringRef name) {
  return IsBlacklistedFunctionName(name) ||
         IsBlacklistedInstanceMethodName(name);
}

bool IsBlacklistedFunction(const clang::FunctionDecl& decl) {
  if (!decl.getDeclName().isIdentifier())
    return false;

  clang::StringRef name = decl.getName();
  return IsBlacklistedFunctionName(name) || IsBlacklistedFreeFunctionName(name);
}

bool IsBlacklistedMethod(const clang::CXXMethodDecl& decl) {
  if (!decl.getDeclName().isIdentifier())
    return false;

  clang::StringRef name = decl.getName();
  if (IsBlacklistedFunctionName(name))
    return true;

  // Remaining cases are only applicable to instance methods.
  if (decl.isStatic())
    return false;

  if (IsBlacklistedInstanceMethodName(name))
    return true;

  // Subclasses of InspectorAgent will subclass "disable()" from both blink and
  // from gen/, which is problematic, but DevTools folks don't want to rename
  // it or split this up. So don't rename it at all.
  if (name.equals("disable") &&
      IsMethodOverrideOf(decl, "blink::InspectorBaseAgent"))
    return true;

  return false;
}

AST_MATCHER(clang::FunctionDecl, isBlacklistedFunction) {
  return IsBlacklistedFunction(Node);
}

AST_MATCHER(clang::CXXMethodDecl, isBlacklistedMethod) {
  return IsBlacklistedMethod(Node);
}

bool IsKnownTraitName(clang::StringRef name) {
  // This set of names is globally a type trait throughout chromium.
  return name == "safeToCompareToEmptyOrDeleted";
}

AST_MATCHER(clang::VarDecl, isKnownTraitName) {
  return Node.getDeclName().isIdentifier() && IsKnownTraitName(Node.getName());
}

AST_MATCHER(clang::Decl, isDeclInGeneratedFile) {
  // This matcher mimics the built-in isExpansionInFileMatching matcher from
  // llvm/tools/clang/include/clang/ASTMatchers/ASTMatchers.h, except:
  // - It special cases some files (e.g. doesn't skip renaming of identifiers
  //   from gen/blink/core/ComputedStyleBase.h)

  const clang::SourceManager& source_manager =
      Node.getASTContext().getSourceManager();

  // TODO(lukasza): Consider using getSpellingLoc below.
  // The built-in isExpansionInFileMatching matcher uses getExpansionLoc below.
  // We could consider using getSpellingLoc (which properly handles things like
  // SETTINGS_GETTERS_AND_SETTERS macro which is defined in generated code
  // (gen/blink/core/SettingsMacros.h), but expanded in non-generated code
  // (third_party/WebKit/Source/core/frame/Settings.h).
  clang::SourceLocation loc =
      source_manager.getExpansionLoc(Node.getLocStart());

  // TODO(lukasza): jump out of scratch space if token concatenation was used.
  if (loc.isInvalid())
    return false;

  const clang::FileEntry* file_entry =
      source_manager.getFileEntryForID(source_manager.getFileID(loc));
  if (!file_entry)
    return false;

  bool is_generated_file = false;
  bool is_computed_style_base_cpp =
      llvm::sys::path::filename(file_entry->getName())
          .equals("ComputedStyleBase.h");
  for (auto it = llvm::sys::path::begin(file_entry->getName());
       it != llvm::sys::path::end(file_entry->getName()); ++it) {
    if (it->equals("gen")) {
      is_generated_file = true;
      break;
    }
  }
  // ComputedStyleBase is intentionally not treated as a generated file, since
  // style definitions are split between generated and non-generated code. It's
  // easier to have the tool just automatically rewrite references to generated
  // code as well, with a small manual patch to fix the code generators.
  return is_generated_file && !is_computed_style_base_cpp;
}

// Helper to convert from a camelCaseName to camel_case_name. It uses some
// heuristics to try to handle acronyms in camel case names correctly.
std::string CamelCaseToUnderscoreCase(StringRef input) {
  std::string output;
  bool needs_underscore = false;
  bool was_lowercase = false;
  bool was_uppercase = false;
  bool first_char = true;
  // Iterate in reverse to minimize the amount of backtracking.
  for (const unsigned char* i = input.bytes_end() - 1; i >= input.bytes_begin();
       --i) {
    char c = *i;
    bool is_lowercase = clang::isLowercase(c);
    bool is_uppercase = clang::isUppercase(c);
    c = clang::toLowercase(c);
    // Transitioning from upper to lower case requires an underscore. This is
    // needed to handle names with acronyms, e.g. handledHTTPRequest needs a '_'
    // in 'dH'. This is a complement to the non-acronym case further down.
    if (was_uppercase && is_lowercase)
      needs_underscore = true;
    if (needs_underscore) {
      output += '_';
      needs_underscore = false;
    }
    output += c;
    // Handles the non-acronym case: transitioning from lower to upper case
    // requires an underscore when emitting the next character, e.g. didLoad
    // needs a '_' in 'dL'.
    if (!first_char && was_lowercase && is_uppercase)
      needs_underscore = true;
    was_lowercase = is_lowercase;
    was_uppercase = is_uppercase;
    first_char = false;
  }
  std::reverse(output.begin(), output.end());
  return output;
}

bool CanBeEvaluatedAtCompileTime(const clang::Stmt* stmt,
                                 const clang::ASTContext& context) {
  auto* expr = clang::dyn_cast<clang::Expr>(stmt);
  if (!expr) {
    // If the statement is not an expression then it's a constant.
    return true;
  }

  // Function calls create non-consistent behaviour. For some template
  // instantiations they can be constexpr while for others they are not, which
  // changes the output of isEvaluatable().
  if (expr->hasNonTrivialCall(context))
    return false;

  // Recurse on children. If they are all const (or are uses of template
  // input) then the statement can be considered const. For whatever reason the
  // below checks can give different-and-less-consistent responses if we call
  // them on a complex expression than if we call them on the most primitive
  // pieces (some pieces would say false but the whole thing says true).
  for (auto* child : expr->children()) {
    if (!CanBeEvaluatedAtCompileTime(child, context))
      return false;
  }

  // If the expression depends on template input, we can not call
  // isEvaluatable() on it as it will do bad things/crash.
  if (!expr->isInstantiationDependent()) {
    // If the expression can be evaluated at compile time, then it should have a
    // kFoo style name. Otherwise, not.
    return expr->isEvaluatable(context);
  }

  // We do our best to figure out special cases as we come across them here, for
  // template dependent situations. Some cases in code are only considered
  // instantiation dependent for some template instantiations! Which is
  // terrible! So most importantly we try to match isEvaluatable in those cases.
  switch (expr->getStmtClass()) {
    case clang::Stmt::CXXThisExprClass:
      return false;
    case clang::Stmt::DeclRefExprClass: {
      auto* declref = clang::dyn_cast<clang::DeclRefExpr>(expr);
      auto* decl = declref->getDecl();
      if (auto* vardecl = clang::dyn_cast<clang::VarDecl>(decl)) {
        if (auto* initializer = vardecl->getInit())
          return CanBeEvaluatedAtCompileTime(initializer, context);
        return false;
      }
      break;
    }

    default:
      break;
  }

  // Otherwise, we consider depending on template parameters to not interfere
  // with being const.. with exceptions hopefully covered above.
  return true;
}

bool IsProbablyConst(const clang::VarDecl& decl,
                     const clang::ASTContext& context) {
  clang::QualType type = decl.getType();
  if (!type.isConstQualified())
    return false;

  if (type.isVolatileQualified())
    return false;

  if (decl.isConstexpr())
    return true;

  // Parameters should not be renamed to |kFooBar| style (even if they are
  // const and have an initializer (aka default value)).
  if (clang::isa<clang::ParmVarDecl>(&decl))
    return false;

  // http://google.github.io/styleguide/cppguide.html#Constant_Names
  // Static variables that are const-qualified should use kConstantStyle naming.
  if (decl.getStorageDuration() == clang::SD_Static)
    return true;

  const clang::Expr* initializer = decl.getInit();
  if (!initializer)
    return false;

  return CanBeEvaluatedAtCompileTime(initializer, context);
}

AST_MATCHER_P(clang::QualType, hasString, std::string, ExpectedString) {
  return ExpectedString == Node.getAsString();
}

bool ShouldPrefixFunctionName(const std::string& old_method_name) {
  // Functions that are named similarily to a type - they should be prefixed
  // with a "Get" prefix.
  static const char* kConflictingMethods[] = {"accumulatorMap",
                                              "animationWorklet",
                                              "attrNodeList",
                                              "audioWorklet",
                                              "binaryType",
                                              "blob",
                                              "channelCountMode",
                                              "color",
                                              "compositorElementId",
                                              "constructionStack",
                                              "controlSize",
                                              "counterDirectives",
                                              "counterMaps",
                                              "document",
                                              "dragOperation",
                                              "element",
                                              "emptyChromeClient",
                                              "emptyEditorClient",
                                              "emptySpellCheckerClient",
                                              "entryType",
                                              "error",
                                              "eventTargetDataMap",
                                              "fileUtilities",
                                              "font",
                                              "frame",
                                              "frameBlameContext",
                                              "frontend",
                                              "gridCell",
                                              "harfBuzzFontCache",
                                              "hash",
                                              "heapObjectHeader",
                                              "heapObjectSet",
                                              "iconURL",
                                              "image",
                                              "infoMap",
                                              "inputMethodController",
                                              "inputType",
                                              "interpolationTypes",
                                              "intervalArena",
                                              "layout",
                                              "layoutBlock",
                                              "layoutObject",
                                              "layoutSize",
                                              "lineCap",
                                              "lineEndings",
                                              "lineJoin",
                                              "listItems",
                                              "locationInBackingMap",
                                              "matchedProperties",
                                              "midpointState",
                                              "modifiers",
                                              "mouseEvent",
                                              "name",
                                              "navigationType",
                                              "node",
                                              "notificationManager",
                                              "originAccessMap",
                                              "outcome",
                                              "pagePopup",
                                              "paintWorklet",
                                              "path",
                                              "position",
                                              "presentationAttributeCache",
                                              "processingInstruction",
                                              "qualifiedNameCache",
                                              "readyState",
                                              "referrer",
                                              "referrerPolicy",
                                              "relList",
                                              "resource",
                                              "response",
                                              "restrictedKeyMap",
                                              "sandboxSupport",
                                              "screenInfo",
                                              "screenOrientationController",
                                              "scrollAnimator",
                                              "scrollbarPainterMap",
                                              "scrollbarSet",
                                              "selectionInDOMTree",
                                              "selectionInFlatTree",
                                              "selectionVisualRectMap",
                                              "selectorTextCache",
                                              "settings",
                                              "shadowRootType",
                                              "signalingState",
                                              "snapshotById",
                                              "state",
                                              "stickyConstraintsMap",
                                              "string",
                                              "styleSharingList",
                                              "styleSheet",
                                              "supplementable",
                                              "text",
                                              "textAlign",
                                              "textBaseline",
                                              "textDirection",
                                              "theme",
                                              "thread",
                                              "timing",
                                              "topLevelBlameContext",
                                              "type",
                                              "vector",
                                              "visibleSelection",
                                              "visibleSelectionInFlatTree",
                                              "weakHeapObjectSet",
                                              "webFrame",
                                              "widget",
                                              "wordBoundaries",
                                              "workerThread",
                                              "worldId",
                                              "worldMap",
                                              "wrapperTypeInfo"};
  for (const auto& conflicting_method : kConflictingMethods) {
    if (old_method_name == conflicting_method)
      return true;
  }

  return false;
}

AST_MATCHER(clang::FunctionDecl, shouldPrefixFunctionName) {
  return Node.getDeclName().isIdentifier() &&
      ShouldPrefixFunctionName(Node.getName().str());
}

bool GetNameForDecl(const clang::FunctionDecl& decl,
                    clang::ASTContext& context,
                    std::string& name) {
  name = decl.getName().str();
  name[0] = clang::toUppercase(name[0]);

  // Given
  //   class Foo {};
  //   class DerivedFoo : class Foo;
  //   using Bar = Foo;
  //   Bar f1();  // <- |Bar| would be matched by hasString("Bar") below.
  //   Bar f2();  // <- |Bar| would be matched by hasName("Foo") below.
  //   DerivedFoo f3();  // <- |DerivedFoo| matched by isDerivedFrom(...) below.
  // |type_with_same_name_as_function| matcher matches Bar and Foo return types.
  auto type_with_same_name_as_function = qualType(anyOf(
      // hasString matches the type as spelled (Bar above).
      hasString(name),
      // hasDeclaration matches resolved type (Foo or DerivedFoo above).
      hasDeclaration(namedDecl(hasName(name)))));

  // |type_containing_same_name_as_function| matcher will match all of the
  // return types below:
  // - Foo foo()  // Direct application of |type_with_same_name_as_function|.
  // - Foo* foo()  // |hasDescendant| traverses references/pointers.
  // - RefPtr<Foo> foo()  // |hasDescendant| traverses template arguments.
  auto type_containing_same_name_as_function =
      qualType(anyOf(type_with_same_name_as_function,
                     hasDescendant(type_with_same_name_as_function)));
  // https://crbug.com/582312: Prepend "Get" if method name conflicts with
  // return type.
  auto conflict_matcher = functionDecl(anyOf(
      // For functions and non-virtual or base method implementations just
      // compare with the immediate return type.
      functionDecl(returns(type_containing_same_name_as_function),
                   unless(cxxMethodDecl(isOverride()))),
      // For methods that override one or more methods, compare with the return
      // type of the *base* methods.
      cxxMethodDecl(isOverride(), forEachOverridden(returns(
                                      type_containing_same_name_as_function))),
      // And also check hardcoded list of function names to prefix with "Get".
      shouldPrefixFunctionName()));
  if (IsMatching(conflict_matcher, decl, context))
    name = "Get" + name;

  return true;
}

bool GetNameForDecl(const clang::EnumConstantDecl& decl,
                    clang::ASTContext& context,
                    std::string& name) {
  StringRef original_name = decl.getName();

  // If it's already correct leave it alone.
  if (original_name.size() >= 2 && original_name[0] == 'k' &&
      clang::isUppercase(original_name[1]))
    return false;

  bool is_shouty = true;
  for (char c : original_name) {
    if (!clang::isUppercase(c) && !clang::isDigit(c) && c != '_') {
      is_shouty = false;
      break;
    }
  }

  if (is_shouty)
    return false;

  name = 'k';  // k prefix on enum values.
  name += original_name;
  name[1] = clang::toUppercase(name[1]);
  return true;
}

bool GetNameForDecl(const clang::FieldDecl& decl,
                    clang::ASTContext& context,
                    std::string& name) {
  StringRef original_name = decl.getName();
  bool member_prefix = original_name.startswith(kBlinkFieldPrefix);

  StringRef rename_part = !member_prefix
                              ? original_name
                              : original_name.substr(strlen(kBlinkFieldPrefix));
  name = CamelCaseToUnderscoreCase(rename_part);

  // Assume that prefix of m_ was intentional and always replace it with a
  // suffix _.
  if (member_prefix && name.back() != '_')
    name += '_';

  return true;
}

bool GetNameForDecl(const clang::VarDecl& decl,
                    clang::ASTContext& context,
                    std::string& name) {
  StringRef original_name = decl.getName();

  // Nothing to do for unnamed parameters.
  if (clang::isa<clang::ParmVarDecl>(decl) && original_name.empty())
    return false;

  // This is a type trait that appears in consumers of WTF as well as inside
  // WTF. We want it to be named in this_style_of_case accordingly.
  if (IsKnownTraitName(original_name)) {
    name = CamelCaseToUnderscoreCase(original_name);
    return true;
  }

  // static class members match against VarDecls. Blink style dictates that
  // these should be prefixed with `s_`, so strip that off. Also check for `m_`
  // and strip that off too, for code that accidentally uses the wrong prefix.
  if (original_name.startswith(kBlinkStaticMemberPrefix))
    original_name = original_name.substr(strlen(kBlinkStaticMemberPrefix));
  else if (original_name.startswith(kBlinkFieldPrefix))
    original_name = original_name.substr(strlen(kBlinkFieldPrefix));

  bool is_const = IsProbablyConst(decl, context);
  if (is_const) {
    // Don't try to rename constants that already conform to Chrome style.
    if (original_name.size() >= 2 && original_name[0] == 'k' &&
        clang::isUppercase(original_name[1]))
      return false;
    // Or names are spelt with underscore casing. While they are actually
    // compile consts, the author wrote it explicitly as a variable not as
    // a constant (they would have used kFormat otherwise here), so preserve
    // it rather than try to mangle a kFormat out of it.
    if (original_name.find('_') != StringRef::npos)
      return false;

    name = 'k';
    name.append(original_name.data(), original_name.size());
    name[1] = clang::toUppercase(name[1]);
  } else {
    name = CamelCaseToUnderscoreCase(original_name);

    // Non-const variables with static storage duration at namespace scope are
    // prefixed with `g_' to reduce the likelihood of a naming collision.
    const clang::DeclContext* decl_context = decl.getDeclContext();
    if (name.find("g_") != 0 && decl.hasGlobalStorage() &&
        decl_context->isNamespace())
      name.insert(0, "g_");
  }

  // Static members end with _ just like other members, but constants should
  // not.
  if (!is_const && decl.isStaticDataMember()) {
    name += '_';
  }

  return true;
}

bool GetNameForDecl(const clang::FunctionTemplateDecl& decl,
                    clang::ASTContext& context,
                    std::string& name) {
  clang::FunctionDecl* templated_function = decl.getTemplatedDecl();
  return GetNameForDecl(*templated_function, context, name);
}

bool GetNameForDecl(const clang::NamedDecl& decl,
                    clang::ASTContext& context,
                    std::string& name) {
  if (auto* function = clang::dyn_cast<clang::FunctionDecl>(&decl))
    return GetNameForDecl(*function, context, name);
  if (auto* var = clang::dyn_cast<clang::VarDecl>(&decl))
    return GetNameForDecl(*var, context, name);
  if (auto* field = clang::dyn_cast<clang::FieldDecl>(&decl))
    return GetNameForDecl(*field, context, name);
  if (auto* function_template =
          clang::dyn_cast<clang::FunctionTemplateDecl>(&decl))
    return GetNameForDecl(*function_template, context, name);
  if (auto* enumc = clang::dyn_cast<clang::EnumConstantDecl>(&decl))
    return GetNameForDecl(*enumc, context, name);

  return false;
}

bool GetNameForDecl(const clang::UsingDecl& decl,
                    clang::ASTContext& context,
                    std::string& name) {
  assert(decl.shadow_size() > 0);

  // If a using declaration's targeted declaration is a set of overloaded
  // functions, it can introduce multiple shadowed declarations. Just using the
  // first one is OK, since overloaded functions have the same name, by
  // definition.
  return GetNameForDecl(*decl.shadow_begin()->getTargetDecl(), context, name);
}

template <typename Type>
struct TargetNodeTraits;

template <>
struct TargetNodeTraits<clang::NamedDecl> {
  static clang::SourceLocation GetLoc(const clang::NamedDecl& decl) {
    return decl.getLocation();
  }
  static const char* GetName() { return "decl"; }
  static const char* GetType() { return "NamedDecl"; }
};

template <>
struct TargetNodeTraits<clang::MemberExpr> {
  static clang::SourceLocation GetLoc(const clang::MemberExpr& expr) {
    return expr.getMemberLoc();
  }
  static const char* GetName() { return "expr"; }
  static const char* GetType() { return "MemberExpr"; }
};

template <>
struct TargetNodeTraits<clang::DeclRefExpr> {
  static clang::SourceLocation GetLoc(const clang::DeclRefExpr& expr) {
    return expr.getLocation();
  }
  static const char* GetName() { return "expr"; }
  static const char* GetType() { return "DeclRefExpr"; }
};

template <>
struct TargetNodeTraits<clang::DependentScopeDeclRefExpr> {
  static clang::SourceLocation GetLoc(
      const clang::DependentScopeDeclRefExpr& expr) {
    return expr.getLocation();
  }
  static const char* GetName() { return "expr"; }
};

template <>
struct TargetNodeTraits<clang::CXXDependentScopeMemberExpr> {
  static clang::SourceLocation GetLoc(
      const clang::CXXDependentScopeMemberExpr& expr) {
    return expr.getMemberLoc();
  }
  static const char* GetName() { return "expr"; }
};

template <>
struct TargetNodeTraits<clang::CXXCtorInitializer> {
  static clang::SourceLocation GetLoc(const clang::CXXCtorInitializer& init) {
    assert(init.isWritten());
    return init.getSourceLocation();
  }
  static const char* GetName() { return "initializer"; }
  static const char* GetType() { return "CXXCtorInitializer"; }
};

template <>
struct TargetNodeTraits<clang::UnresolvedLookupExpr> {
  static clang::SourceLocation GetLoc(const clang::UnresolvedLookupExpr& expr) {
    return expr.getNameLoc();
  }
  static const char* GetName() { return "expr"; }
  static const char* GetType() { return "UnresolvedLookupExpr"; }
};

template <>
struct TargetNodeTraits<clang::UnresolvedMemberExpr> {
  static clang::SourceLocation GetLoc(const clang::UnresolvedMemberExpr& expr) {
    return expr.getMemberLoc();
  }
  static const char* GetName() { return "expr"; }
  static const char* GetType() { return "UnresolvedMemberExpr"; }
};

template <>
struct TargetNodeTraits<clang::UnresolvedUsingValueDecl> {
  static clang::SourceLocation GetLoc(
      const clang::UnresolvedUsingValueDecl& decl) {
    return decl.getNameInfo().getLoc();
  }
  static const char* GetName() { return "decl"; }
  static const char* GetType() { return "UnresolvedUsingValueDecl"; }
};

template <typename TargetNode>
class RewriterBase : public MatchFinder::MatchCallback {
 public:
  explicit RewriterBase(std::set<Replacement>* replacements,
                        RenameCategory category)
      : replacements_(replacements), edit_tracker_(category) {}

  const TargetNode& GetTargetNode(const MatchFinder::MatchResult& result) {
    const TargetNode* target_node = result.Nodes.getNodeAs<TargetNode>(
        TargetNodeTraits<TargetNode>::GetName());
    assert(target_node);
    return *target_node;
  }

  bool GenerateReplacement(const MatchFinder::MatchResult& result,
                           clang::SourceLocation loc,
                           llvm::StringRef old_name,
                           std::string new_name,
                           Replacement* replacement) {
    const clang::ASTContext& context = *result.Context;
    const clang::SourceManager& source_manager = *result.SourceManager;

    if (loc.isMacroID()) {
      // Try to jump "above" the scratch buffer if |loc| is inside
      // token##Concatenation.
      const int kMaxJumps = 5;
      bool verified_out_of_scratch_space = false;
      for (int i = 0; i < kMaxJumps && !verified_out_of_scratch_space; i++) {
        clang::SourceLocation spell = source_manager.getSpellingLoc(loc);
        verified_out_of_scratch_space =
            source_manager.getBufferName(spell) != "<scratch space>";
        if (!verified_out_of_scratch_space)
          loc = source_manager.getImmediateMacroCallerLoc(loc);
      }
      if (!verified_out_of_scratch_space)
        return false;
    }

    // If the edit affects only the first character of the identifier, then
    // narrow down the edit to only this single character.  This is important
    // for dealing with toFooBar -> ToFooBar method renaming when the method
    // name is built using macro token concatenation like to##macroArgument - in
    // this case we should only rewrite "t" -> "T" and leave "o##macroArgument"
    // untouched.
    llvm::StringRef expected_old_text = old_name;
    llvm::StringRef new_text = new_name;
    if (loc.isMacroID() && expected_old_text.substr(1) == new_text.substr(1)) {
      expected_old_text = expected_old_text.substr(0, 1);
      new_text = new_text.substr(0, 1);
    }
    clang::SourceLocation spell = source_manager.getSpellingLoc(loc);
    clang::CharSourceRange range = clang::CharSourceRange::getCharRange(
        spell, spell.getLocWithOffset(expected_old_text.size()));

    // We need to ensure that |actual_old_text| is the same as
    // |expected_old_text| - it can be different if |actual_old_text| contains
    // a macro argument (see DEFINE_WITH_TOKEN_CONCATENATION2 in
    // macros-original.cc testcase).
    StringRef actual_old_text = clang::Lexer::getSourceText(
        range, source_manager, context.getLangOpts());
    if (actual_old_text != expected_old_text)
      return false;

    if (replacement) {
      // If there's already a replacement for this location, don't emit any
      // other replacements to avoid potential naming conflicts. This is
      // primarily to avoid problems when a function and a parameter are defined
      // by the same macro argument.
      if (!GetRewrittenLocs().emplace(spell).second)
        return false;

      *replacement = Replacement(source_manager, range, new_text);
    }
    return true;
  }

  virtual clang::SourceLocation GetTargetLoc(
      const MatchFinder::MatchResult& result) {
    return TargetNodeTraits<TargetNode>::GetLoc(GetTargetNode(result));
  }

  void AddReplacement(const MatchFinder::MatchResult& result,
                      llvm::StringRef old_name,
                      std::string new_name) {
    if (old_name == new_name)
      return;

    clang::SourceLocation loc = GetTargetLoc(result);
    if (loc.isInvalid())
      return;

    Replacement replacement;
    if (!GenerateReplacement(result, loc, old_name, new_name, &replacement))
      return;

    replacements_->insert(std::move(replacement));
    edit_tracker_.Add(*result.SourceManager, loc, old_name, new_name);
  }

  const EditTracker* edit_tracker() const { return &edit_tracker_; }

 private:
  std::set<Replacement>* const replacements_;
  EditTracker edit_tracker_;
};

template <typename DeclNode>
RenameCategory GetCategory();
template <>
RenameCategory GetCategory<clang::FieldDecl>() {
  return RenameCategory::kField;
}
template <>
RenameCategory GetCategory<clang::VarDecl>() {
  return RenameCategory::kVariable;
}
template <>
RenameCategory GetCategory<clang::FunctionDecl>() {
  return RenameCategory::kFunction;
}
template <>
RenameCategory GetCategory<clang::CXXMethodDecl>() {
  return RenameCategory::kFunction;
}
template <>
RenameCategory GetCategory<clang::EnumConstantDecl>() {
  return RenameCategory::kEnumValue;
}
template <>
RenameCategory GetCategory<clang::NamedDecl>() {
  return RenameCategory::kUnresolved;
}
template <>
RenameCategory GetCategory<clang::UsingDecl>() {
  return RenameCategory::kUnresolved;
}

template <typename DeclNode, typename TargetNode>
class DeclRewriterBase : public RewriterBase<TargetNode> {
 public:
  using Base = RewriterBase<TargetNode>;

  explicit DeclRewriterBase(std::set<Replacement>* replacements)
      : Base(replacements, GetCategory<DeclNode>()) {}

  void run(const MatchFinder::MatchResult& result) override {
    const DeclNode* decl = result.Nodes.getNodeAs<DeclNode>("decl");
    if (!decl->getDeclName().isIdentifier())
      return;

    assert(decl);
    llvm::StringRef old_name = decl->getName();

    // Return early if there's no name to be renamed.
    if (!decl->getIdentifier())
      return;

    // Get the new name.
    std::string new_name;
    if (!GetNameForDecl(*decl, *result.Context, new_name))
      return;  // If false, the name was not suitable for renaming.

    // Check if we are able to rewrite the decl (to avoid rewriting if the
    // decl's identifier is part of macro##Token##Concatenation).
    clang::SourceLocation decl_loc =
        TargetNodeTraits<clang::NamedDecl>::GetLoc(*decl);
    if (!Base::GenerateReplacement(result, decl_loc, old_name, new_name,
                                   nullptr))
      return;

    Base::AddReplacement(result, old_name, std::move(new_name));
  }
};

using FieldDeclRewriter = DeclRewriterBase<clang::FieldDecl, clang::NamedDecl>;
using VarDeclRewriter = DeclRewriterBase<clang::VarDecl, clang::NamedDecl>;
using MemberRewriter = DeclRewriterBase<clang::FieldDecl, clang::MemberExpr>;
using DeclRefRewriter = DeclRewriterBase<clang::VarDecl, clang::DeclRefExpr>;
using FieldDeclRefRewriter =
    DeclRewriterBase<clang::FieldDecl, clang::DeclRefExpr>;
using FunctionDeclRewriter =
    DeclRewriterBase<clang::FunctionDecl, clang::NamedDecl>;
using FunctionRefRewriter =
    DeclRewriterBase<clang::FunctionDecl, clang::DeclRefExpr>;
using ConstructorInitializerRewriter =
    DeclRewriterBase<clang::FieldDecl, clang::CXXCtorInitializer>;

using MethodDeclRewriter =
    DeclRewriterBase<clang::CXXMethodDecl, clang::NamedDecl>;
using MethodRefRewriter =
    DeclRewriterBase<clang::CXXMethodDecl, clang::DeclRefExpr>;
using MethodMemberRewriter =
    DeclRewriterBase<clang::CXXMethodDecl, clang::MemberExpr>;

using EnumConstantDeclRewriter =
    DeclRewriterBase<clang::EnumConstantDecl, clang::NamedDecl>;
using EnumConstantDeclRefRewriter =
    DeclRewriterBase<clang::EnumConstantDecl, clang::DeclRefExpr>;

using UnresolvedLookupRewriter =
    DeclRewriterBase<clang::NamedDecl, clang::UnresolvedLookupExpr>;
using UnresolvedMemberRewriter =
    DeclRewriterBase<clang::NamedDecl, clang::UnresolvedMemberExpr>;

using UsingDeclRewriter = DeclRewriterBase<clang::UsingDecl, clang::NamedDecl>;

class GMockMemberRewriter
    : public DeclRewriterBase<clang::CXXMethodDecl, clang::MemberExpr> {
 public:
  using Base = DeclRewriterBase<clang::CXXMethodDecl, clang::MemberExpr>;

  explicit GMockMemberRewriter(std::set<Replacement>* replacements)
      : Base(replacements) {}

  std::unique_ptr<clang::PPCallbacks> CreatePreprocessorCallbacks() {
    return llvm::make_unique<GMockMemberRewriter::PPCallbacks>(this);
  }

  clang::SourceLocation GetTargetLoc(
      const MatchFinder::MatchResult& result) override {
    // Find location of the gmock_##MockedMethod identifier.
    clang::SourceLocation target_loc = Base::GetTargetLoc(result);

    // Find location of EXPECT_CALL or ON_CALL macro invocation.
    clang::SourceLocation macro_call_loc =
        result.SourceManager->getExpansionLoc(target_loc);

    // Map |macro_call_loc| to argument location (location of the method name
    // that needs renaming).
    auto it = gmock_macro_call_to_2nd_arg.find(macro_call_loc);
    if (it == gmock_macro_call_to_2nd_arg.end())
      return clang::SourceLocation();
    return it->second;
  }

 private:
  std::map<clang::SourceLocation, clang::SourceLocation>
      gmock_macro_call_to_2nd_arg;

  // Called from PPCallbacks with the locations of EXPECT_CALL and ON_CALL macro
  // invocation.  Example:
  //   EXPECT_CALL(my_mock, myMethod(123, 456));
  //   ^- expansion_loc     ^- actual_arg_loc
  void RecordGMockMacroInvocation(clang::SourceLocation expansion_loc,
                                  clang::SourceLocation second_arg_loc) {
    gmock_macro_call_to_2nd_arg[expansion_loc] = second_arg_loc;
  }

  class PPCallbacks : public clang::PPCallbacks {
   public:
    explicit PPCallbacks(GMockMemberRewriter* rewriter) : rewriter_(rewriter) {}
    ~PPCallbacks() override {}
    void MacroExpands(const clang::Token& name,
                      const clang::MacroDefinition& def,
                      clang::SourceRange range,
                      const clang::MacroArgs* args) override {
      clang::IdentifierInfo* id = name.getIdentifierInfo();
      if (!id)
        return;

      if (id->getName() != "EXPECT_CALL" && id->getName() != "ON_CALL")
        return;

      if (def.getMacroInfo()->getNumParams() != 2)
        return;

      // TODO(lukasza): Should check if def.getMacroInfo()->getDefinitionLoc()
      // is in testing/gmock/include/gmock/gmock-spec-builders.h but I don't
      // know how to get clang::SourceManager to call getFileName.

      rewriter_->RecordGMockMacroInvocation(
          name.getLocation(), args->getUnexpArgument(1)->getLocation());
    }

   private:
    GMockMemberRewriter* rewriter_;
  };
};

clang::DeclarationName GetUnresolvedName(
    const clang::UnresolvedMemberExpr& expr) {
  return expr.getMemberName();
}

clang::DeclarationName GetUnresolvedName(
    const clang::DependentScopeDeclRefExpr& expr) {
  return expr.getDeclName();
}

clang::DeclarationName GetUnresolvedName(
    const clang::CXXDependentScopeMemberExpr& expr) {
  return expr.getMember();
}

clang::DeclarationName GetUnresolvedName(
    const clang::UnresolvedUsingValueDecl& decl) {
  return decl.getDeclName();
}

// Returns whether |expr_node| is used as a callee in the AST (i.e. if
// |expr_node| needs to resolve to a method or a function).
bool IsCallee(const clang::Expr& expr, clang::ASTContext& context) {
  auto matcher = stmt(hasParent(callExpr(callee(equalsNode(&expr)))));
  return IsMatching(matcher, expr, context);
}

// Returns whether |decl| will be used as a callee in the AST (i.e. if the value
// brought by the using declaration will resolve to a method or a function).
bool IsCallee(const clang::UnresolvedUsingValueDecl& decl,
              clang::ASTContext& /* context */) {
  // Caller (i.e. GuessNameForUnresolvedDependentNode) should have already
  // filtered out fields before calling |IsCallee|.
  clang::IdentifierInfo* info = GetUnresolvedName(decl).getAsIdentifierInfo();
  assert(info);
  bool name_looks_like_a_field = info->getName().startswith(kBlinkFieldPrefix);
  assert(!name_looks_like_a_field);

  // Looking just at clang::UnresolvedUsingValueDecl, we cannot tell whether it
  // refers to something callable or not.  Since fields should have been already
  // filtered out before calling IsCallee (see the assert above), let's assume
  // that |using Base::foo| refers to a method.
  return true;
}

template <typename TargetNode>
class UnresolvedRewriterBase : public RewriterBase<TargetNode> {
 public:
  using Base = RewriterBase<TargetNode>;

  explicit UnresolvedRewriterBase(std::set<Replacement>* replacements)
      : RewriterBase<TargetNode>(replacements, RenameCategory::kUnresolved) {}

  void run(const MatchFinder::MatchResult& result) override {
    const TargetNode& node = Base::GetTargetNode(result);

    clang::DeclarationName decl_name = GetUnresolvedName(node);
    switch (decl_name.getNameKind()) {
      // Do not rewrite this:
      //   return operator T*();
      // into this:
      //   return Operator type - parameter - 0 - 0 * T * ();
      case clang::DeclarationName::NameKind::CXXConversionFunctionName:
      case clang::DeclarationName::NameKind::CXXOperatorName:
      case clang::DeclarationName::NameKind::CXXLiteralOperatorName:
        return;
      default:
        break;
    }

    // Make sure there is an old name + extract the old name.
    clang::IdentifierInfo* info = GetUnresolvedName(node).getAsIdentifierInfo();
    if (!info)
      return;
    llvm::StringRef old_name = info->getName();

    // Try to guess a new name.
    std::string new_name;
    if (GuessNameForUnresolvedDependentNode(node, *result.Context, old_name,
                                            new_name))
      Base::AddReplacement(result, old_name, std::move(new_name));
  }

 private:
  // This method calculates a new name for nodes that depend on template
  // parameters (http://en.cppreference.com/w/cpp/language/dependent_name).  The
  // renaming is based on crude heuristics, because such nodes are not bound to
  // a specific decl until template instantiation - at the point of rename, one
  // cannot tell whether the node will eventually resolve to a field / method /
  // constant / etc.
  //
  // The method returns false if no renaming should be done.
  // Otherwise the method returns true and sets |new_name|.
  bool GuessNameForUnresolvedDependentNode(const TargetNode& node,
                                           clang::ASTContext& context,
                                           llvm::StringRef old_name,
                                           std::string& new_name) {
    // |m_fieldName| -> |field_name_|.
    if (old_name.startswith(kBlinkFieldPrefix)) {
      std::string field_name = old_name.substr(strlen(kBlinkFieldPrefix));
      if (field_name.find('_') == std::string::npos) {
        new_name = CamelCaseToUnderscoreCase(field_name) + "_";
        return true;
      }
    }

    // |T::myMethod(...)| -> |T::MyMethod(...)|.
    if ((old_name.find('_') == std::string::npos) && IsCallee(node, context) &&
        !IsBlacklistedMethodName(old_name)) {
      new_name = old_name;
      new_name[0] = clang::toUppercase(old_name[0]);
      if (ShouldPrefixFunctionName(old_name))
        new_name = "Get" + new_name;
      return true;
    }

    // In the future we can consider more heuristics:
    // - "s_" and "g_" prefixes
    // - "ALL_CAPS"
    // - |T::myStaticField| -> |T::kMyStaticField|
    //   (but have to be careful not to rename |value| in WTF/TypeTraits.h?)
    return false;
  }
};

using UnresolvedDependentMemberRewriter =
    UnresolvedRewriterBase<clang::UnresolvedMemberExpr>;

using UnresolvedUsingValueDeclRewriter =
    UnresolvedRewriterBase<clang::UnresolvedUsingValueDecl>;

using DependentScopeDeclRefExprRewriter =
    UnresolvedRewriterBase<clang::DependentScopeDeclRefExpr>;

using CXXDependentScopeMemberExprRewriter =
    UnresolvedRewriterBase<clang::CXXDependentScopeMemberExpr>;

class SourceFileCallbacks : public clang::tooling::SourceFileCallbacks {
 public:
  explicit SourceFileCallbacks(GMockMemberRewriter* gmock_member_rewriter)
      : gmock_member_rewriter_(gmock_member_rewriter) {
    assert(gmock_member_rewriter);
  }

  ~SourceFileCallbacks() override {}

  // clang::tooling::SourceFileCallbacks override:
  bool handleBeginSource(clang::CompilerInstance& compiler) override {
    compiler.getPreprocessor().addPPCallbacks(
        gmock_member_rewriter_->CreatePreprocessorCallbacks());
    return true;
  }

 private:
  GMockMemberRewriter* gmock_member_rewriter_;
};

}  // namespace

static llvm::cl::extrahelp common_help(CommonOptionsParser::HelpMessage);

int main(int argc, const char* argv[]) {
  // TODO(dcheng): Clang tooling should do this itself.
  // http://llvm.org/bugs/show_bug.cgi?id=21627
  llvm::InitializeNativeTarget();
  llvm::InitializeNativeTargetAsmParser();
  llvm::cl::OptionCategory category(
      "rewrite_to_chrome_style: convert Blink style to Chrome style.");
  llvm::cl::opt<std::string> blocklisted_methods_file(
      kMethodBlocklistParamName, llvm::cl::value_desc("filepath"),
      llvm::cl::desc("file listing methods to be blocked (not renamed)"));
  CommonOptionsParser options(argc, argv, category);
  MethodBlocklist method_blocklist(blocklisted_methods_file);
  clang::tooling::ClangTool tool(options.getCompilations(),
                                 options.getSourcePathList());

  MatchFinder match_finder;
  std::set<Replacement> replacements;

  // Blink namespace matchers ========
  auto blink_namespace_decl =
      namespaceDecl(anyOf(hasName("blink"), hasName("WTF")),
                    hasParent(translationUnitDecl()));
  auto protocol_namespace_decl =
      namespaceDecl(hasName("protocol"),
                    hasParent(namespaceDecl(hasName("blink"),
                                            hasParent(translationUnitDecl()))));

  // Given top-level compilation unit:
  //   namespace WTF {
  //     void foo() {}
  //   }
  // matches |foo|.
  auto decl_under_blink_namespace =
      decl(hasAncestor(blink_namespace_decl),
           unless(hasAncestor(protocol_namespace_decl)));

  // Given top-level compilation unit:
  //   void WTF::function() {}
  //   void WTF::Class::method() {}
  // matches |WTF::function| and |WTF::Class::method| decls.
  auto decl_has_qualifier_to_blink_namespace =
      declaratorDecl(has(nestedNameSpecifier(
          hasTopLevelPrefix(specifiesNamespace(blink_namespace_decl)))));

  auto in_blink_namespace = decl(
      anyOf(decl_under_blink_namespace, decl_has_qualifier_to_blink_namespace,
            hasAncestor(decl_has_qualifier_to_blink_namespace)),
      unless(hasCanonicalDecl(isDeclInGeneratedFile())));

  // Field, variable, and enum declarations ========
  // Given
  //   int x;
  //   struct S {
  //     int y;
  //     enum { VALUE };
  //   };
  // matches |x|, |y|, and |VALUE|.
  auto field_decl_matcher = id("decl", fieldDecl(in_blink_namespace));
  auto is_type_trait_value =
      varDecl(hasName("value"), hasStaticStorageDuration(), isPublic(),
              hasType(isConstQualified()),
              hasType(type(anyOf(builtinType(), enumType()))),
              unless(hasAncestor(recordDecl(
                  has(cxxMethodDecl(isUserProvided(), isInstanceMethod()))))));
  auto var_decl_matcher =
      id("decl", varDecl(in_blink_namespace, unless(is_type_trait_value)));
  // For known trait names, rename every instance anywhere in the codebase.
  auto type_trait_decl_matcher = id("decl", varDecl(isKnownTraitName()));
  auto enum_member_decl_matcher =
      id("decl", enumConstantDecl(in_blink_namespace));

  FieldDeclRewriter field_decl_rewriter(&replacements);
  match_finder.addMatcher(field_decl_matcher, &field_decl_rewriter);

  VarDeclRewriter var_decl_rewriter(&replacements);
  match_finder.addMatcher(var_decl_matcher, &var_decl_rewriter);
  match_finder.addMatcher(type_trait_decl_matcher, &var_decl_rewriter);

  EnumConstantDeclRewriter enum_member_decl_rewriter(&replacements);
  match_finder.addMatcher(enum_member_decl_matcher, &enum_member_decl_rewriter);

  // Field, variable, and enum references ========
  // Given
  //   bool x = true;
  //   if (x) {
  //     ...
  //   }
  // matches |x| in if (x).
  auto member_matcher = id(
      "expr",
      memberExpr(
          member(field_decl_matcher),
          // Needed to avoid matching member references in functions (which will
          // be an ancestor of the member reference) synthesized by the
          // compiler, such as a synthesized copy constructor.
          // This skips explicitly defaulted functions as well, but that's OK:
          // there's nothing interesting to rewrite in those either.
          unless(hasAncestor(functionDecl(isDefaulted())))));
  auto decl_ref_matcher = id("expr", declRefExpr(to(var_decl_matcher)));
  auto type_trait_ref_matcher =
      id("expr", declRefExpr(to(type_trait_decl_matcher)));
  auto enum_member_ref_matcher =
      id("expr", declRefExpr(to(enum_member_decl_matcher)));

  MemberRewriter member_rewriter(&replacements);
  match_finder.addMatcher(member_matcher, &member_rewriter);

  DeclRefRewriter decl_ref_rewriter(&replacements);
  match_finder.addMatcher(decl_ref_matcher, &decl_ref_rewriter);
  match_finder.addMatcher(type_trait_ref_matcher, &decl_ref_rewriter);

  EnumConstantDeclRefRewriter enum_member_ref_rewriter(&replacements);
  match_finder.addMatcher(enum_member_ref_matcher, &enum_member_ref_rewriter);

  // Member references in a non-member context ========
  // Given
  //   struct S {
  //     typedef int U::*UnspecifiedBoolType;
  //     operator UnspecifiedBoolType() { return s_ ? &U::s_ : 0; }
  //     int s_;
  //   };
  // matches |&U::s_| but not |s_|.
  auto member_ref_matcher = id("expr", declRefExpr(to(field_decl_matcher)));

  FieldDeclRefRewriter member_ref_rewriter(&replacements);
  match_finder.addMatcher(member_ref_matcher, &member_ref_rewriter);

  // Non-method function declarations ========
  // Given
  //   void f();
  //   struct S {
  //     void g();
  //   };
  // matches |f| but not |g|.
  auto function_decl_matcher = id(
      "decl",
      functionDecl(
          unless(anyOf(
              // Methods are covered by the method matchers.
              cxxMethodDecl(),
              // Out-of-line overloaded operators have special names and should
              // never be renamed.
              isOverloadedOperator(),
              // Must be checked after filtering out overloaded operators to
              // prevent asserts about the identifier not being a simple name.
              isBlacklistedFunction(),
              // Functions that look like blocked static methods.
              isBlocklistedMethod(method_blocklist))),
          in_blink_namespace));
  FunctionDeclRewriter function_decl_rewriter(&replacements);
  match_finder.addMatcher(function_decl_matcher, &function_decl_rewriter);

  // Non-method function references ========
  // Given
  //   f();
  //   void (*p)() = &f;
  // matches |f()| and |&f|.
  auto function_ref_matcher = id(
      "expr", declRefExpr(to(function_decl_matcher),
                          // Ignore template substitutions.
                          unless(hasAncestor(substNonTypeTemplateParmExpr()))));
  FunctionRefRewriter function_ref_rewriter(&replacements);
  match_finder.addMatcher(function_ref_matcher, &function_ref_rewriter);

  // Method declarations ========
  // Given
  //   struct S {
  //     void g();
  //   };
  // matches |g|.
  // For a method to be considered for rewrite, it must not override something
  // that we're not rewriting. Any methods that we would not normally consider
  // but that override something we are rewriting should also be rewritten. So
  // we use includeAllOverriddenMethods() to check these rules not just for the
  // method being matched but for the methods it overrides also.
  auto is_blink_method = includeAllOverriddenMethods(
      allOf(in_blink_namespace,
            unless(anyOf(isBlacklistedMethod(),
                         isBlocklistedMethod(method_blocklist)))));
  auto method_decl_matcher = id(
      "decl",
      cxxMethodDecl(
          unless(anyOf(
              // Overloaded operators have special names and should never be
              // renamed.
              isOverloadedOperator(),
              // Similarly, constructors, destructors, and conversion
              // functions should not be considered for renaming.
              cxxConstructorDecl(), cxxDestructorDecl(), cxxConversionDecl())),
          // Check this last after excluding things, to avoid
          // asserts about overriding non-blink and blink for the
          // same method.
          is_blink_method));
  MethodDeclRewriter method_decl_rewriter(&replacements);
  match_finder.addMatcher(method_decl_matcher, &method_decl_rewriter);

  // Method references in a non-member context ========
  // Given
  //   S s;
  //   s.g();
  //   void (S::*p)() = &S::g;
  // matches |&S::g| but not |s.g|.
  auto method_ref_matcher = id(
      "expr", declRefExpr(to(method_decl_matcher),
                          // Ignore template substitutions.
                          unless(hasAncestor(substNonTypeTemplateParmExpr()))));

  MethodRefRewriter method_ref_rewriter(&replacements);
  match_finder.addMatcher(method_ref_matcher, &method_ref_rewriter);

  // Method references in a member context ========
  // Given
  //   S s;
  //   s.g();
  //   void (S::*p)() = &S::g;
  // matches |s.g| but not |&S::g|.
  auto method_member_matcher =
      id("expr", memberExpr(member(method_decl_matcher)));

  MethodMemberRewriter method_member_rewriter(&replacements);
  match_finder.addMatcher(method_member_matcher, &method_member_rewriter);

  // Initializers ========
  // Given
  //   struct S {
  //     int x;
  //     S() : x(2) {}
  //   };
  // matches each initializer in the constructor for S.
  auto constructor_initializer_matcher =
      cxxConstructorDecl(forEachConstructorInitializer(id(
          "initializer",
          cxxCtorInitializer(forAnyField(field_decl_matcher), isWritten()))));

  ConstructorInitializerRewriter constructor_initializer_rewriter(
      &replacements);
  match_finder.addMatcher(constructor_initializer_matcher,
                          &constructor_initializer_rewriter);

  // Unresolved lookup expressions ========
  // Given
  //   template<typename T> void F(T) { }
  //   template<void G(T)> H(T) { }
  //   H<F<int>>(...);
  // matches |F| in |H<F<int>>|.
  //
  // UnresolvedLookupExprs are similar to DeclRefExprs that reference a
  // FunctionDecl, but are used when a candidate FunctionDecl can't be selected.
  // This commonly happens inside uninstantiated template definitions for one of
  // two reasons:
  //
  // 1. If the candidate declaration is a dependent FunctionTemplateDecl, the
  //    actual overload can't be selected until template instantiation time.
  // 2. Alternatively, there might be multiple declarations in the candidate set
  //    if the candidate function has overloads. If any of the function
  //    arguments has a dependent type, then the actual overload can't be
  //    selected until instantiation time either.
  //
  // Another instance where UnresolvedLookupExprs can appear is in a template
  // argument list, like the provided example.
  auto function_template_decl_matcher =
      id("decl", functionTemplateDecl(templatedDecl(function_decl_matcher)));
  auto method_template_decl_matcher =
      id("decl", functionTemplateDecl(templatedDecl(method_decl_matcher)));
  auto unresolved_lookup_matcher = expr(id(
      "expr",
      unresolvedLookupExpr(
          // In order to automatically rename an unresolved lookup, the lookup
          // candidates must either all be Blink functions/function templates or
          // all be Blink methods/method templates. Otherwise, we might end up
          // in a situation where the naming could change depending on the
          // selected candidate.
          anyOf(allOverloadsMatch(anyOf(function_decl_matcher,
                                        function_template_decl_matcher)),
                // Note: this matches references to methods in a non-member
                // context, e.g. Template<&Class::Method>. This and the
                // UnresolvedMemberExpr matcher below are analogous to how the
                // rewriter has both a MemberRefRewriter matcher to rewrite
                // &T::method and a MethodMemberRewriter matcher to rewriter
                // t.method().
                allOverloadsMatch(anyOf(method_decl_matcher,
                                        method_template_decl_matcher))))));
  UnresolvedLookupRewriter unresolved_lookup_rewriter(&replacements);
  match_finder.addMatcher(unresolved_lookup_matcher,
                          &unresolved_lookup_rewriter);

  // Unresolved member expressions (for non-dependent fields / methods) ========
  // Similar to unresolved lookup expressions, but for methods in a member
  // context, e.g. var_with_templated_type.Method().
  auto unresolved_member_matcher = expr(id(
      "expr",
      unresolvedMemberExpr(
          // Similar to UnresolvedLookupExprs, all the candidate methods must be
          // Blink methods/method templates.
          allOverloadsMatch(
              anyOf(method_decl_matcher, method_template_decl_matcher)))));
  UnresolvedMemberRewriter unresolved_member_rewriter(&replacements);
  match_finder.addMatcher(unresolved_member_matcher,
                          &unresolved_member_rewriter);

  // Unresolved using value decls ========
  // Example:
  //  template <typename T>
  //  class BaseClass {
  //   public:
  //    unsigned long m_size;
  //  };
  //  template <typename T>
  //  class DerivedClass : protected BaseClass<T> {
  //   private:
  //    using Base = BaseClass<T>;
  //    using Base::m_size;  // <- |m_size| here is matched by
  //    void method() {      //    |unresolved_using_value_decl_matcher|.
  //      m_size = 123;  // <- |m_size| here is matched by
  //    }                //    |unresolved_dependent_using_matcher|.
  //  };
  auto unresolved_dependent_using_matcher =
      expr(id("expr", unresolvedMemberExpr(allOverloadsMatch(allOf(
                          in_blink_namespace, unresolvedUsingValueDecl())))));
  UnresolvedDependentMemberRewriter unresolved_dependent_member_rewriter(
      &replacements);
  match_finder.addMatcher(unresolved_dependent_using_matcher,
                          &unresolved_dependent_member_rewriter);
  auto unresolved_using_value_decl_matcher =
      decl(id("decl", unresolvedUsingValueDecl(in_blink_namespace)));
  UnresolvedUsingValueDeclRewriter unresolved_using_value_decl_rewriter(
      &replacements);
  match_finder.addMatcher(unresolved_using_value_decl_matcher,
                          &unresolved_using_value_decl_rewriter);

  // Using declarations ========
  // Given
  //   using blink::X;
  // matches |using blink::X|.
  auto using_decl_matcher = id(
      "decl", usingDecl(hasAnyUsingShadowDecl(hasTargetDecl(anyOf(
                  var_decl_matcher, field_decl_matcher, function_decl_matcher,
                  method_decl_matcher, function_template_decl_matcher,
                  method_template_decl_matcher, enum_member_decl_matcher)))));
  UsingDeclRewriter using_decl_rewriter(&replacements);
  match_finder.addMatcher(using_decl_matcher, &using_decl_rewriter);

  // Matches any QualType that refers to a blink type:
  // - const blink::Foo&
  // - blink::Foo*
  // - blink::Foo<T>
  auto blink_qual_type_base_matcher = hasBaseType(hasUnqualifiedDesugaredType(
      anyOf(enumType(hasDeclaration(in_blink_namespace)),
            injectedClassNameType(hasDeclaration(in_blink_namespace)),
            recordType(hasDeclaration(in_blink_namespace)),
            templateSpecializationType(hasDeclaration(in_blink_namespace)),
            templateTypeParmType(hasDeclaration(in_blink_namespace)))));
  auto blink_qual_type_matcher = qualType(anyOf(
      blink_qual_type_base_matcher, pointsTo(blink_qual_type_base_matcher),
      references(blink_qual_type_base_matcher)));

  // Template-dependent decl lookup ========
  // Given
  //   template <typename T> void f() { T::foo(); }
  // matches |T::foo|.
  auto dependent_scope_decl_ref_expr_matcher =
      expr(id("expr", dependentScopeDeclRefExpr(has(nestedNameSpecifier(
                          specifiesType(blink_qual_type_matcher))))));
  DependentScopeDeclRefExprRewriter dependent_scope_decl_ref_expr_rewriter(
      &replacements);
  match_finder.addMatcher(dependent_scope_decl_ref_expr_matcher,
                          &dependent_scope_decl_ref_expr_rewriter);

  // Template-dependent member lookup ========
  // Given
  //   template <typename T>
  //   class Foo {
  //     void f() { T::foo(); }
  //     void g(T x) { x.bar(); }
  //   };
  // matches |T::foo| and |x.bar|.
  auto cxx_dependent_scope_member_expr_matcher =
      expr(id("expr", cxxDependentScopeMemberExpr(
                          hasMemberFromType(blink_qual_type_matcher))));
  CXXDependentScopeMemberExprRewriter cxx_dependent_scope_member_expr_rewriter(
      &replacements);
  match_finder.addMatcher(cxx_dependent_scope_member_expr_matcher,
                          &cxx_dependent_scope_member_expr_rewriter);

  // GMock calls lookup ========
  // Given
  //   EXPECT_CALL(obj, myMethod(...))
  // or
  //   ON_CALL(obj, myMethod(...))
  // will match obj.gmock_myMethod(...) call generated by the macros
  // (but only if it mocks a Blink method).
  auto gmock_member_matcher =
      id("expr", memberExpr(hasDeclaration(
                     decl(cxxMethodDecl(mocksMethod(method_decl_matcher))))));
  GMockMemberRewriter gmock_member_rewriter(&replacements);
  match_finder.addMatcher(gmock_member_matcher, &gmock_member_rewriter);

  // Prepare and run the tool.
  SourceFileCallbacks source_file_callbacks(&gmock_member_rewriter);
  std::unique_ptr<clang::tooling::FrontendActionFactory> factory =
      clang::tooling::newFrontendActionFactory(&match_finder,
                                               &source_file_callbacks);
  int result = tool.run(factory.get());
  if (result != 0)
    return result;

  // Supplemental data for the Blink rename rebase helper.
  std::vector<const EditTracker*> all_edit_trackers{
      field_decl_rewriter.edit_tracker(),
      var_decl_rewriter.edit_tracker(),
      enum_member_decl_rewriter.edit_tracker(),
      member_rewriter.edit_tracker(),
      decl_ref_rewriter.edit_tracker(),
      enum_member_ref_rewriter.edit_tracker(),
      member_ref_rewriter.edit_tracker(),
      function_decl_rewriter.edit_tracker(),
      function_ref_rewriter.edit_tracker(),
      method_decl_rewriter.edit_tracker(),
      method_ref_rewriter.edit_tracker(),
      method_member_rewriter.edit_tracker(),
      constructor_initializer_rewriter.edit_tracker(),
      unresolved_lookup_rewriter.edit_tracker(),
      unresolved_member_rewriter.edit_tracker(),
      unresolved_dependent_member_rewriter.edit_tracker(),
      unresolved_using_value_decl_rewriter.edit_tracker(),
      using_decl_rewriter.edit_tracker(),
      dependent_scope_decl_ref_expr_rewriter.edit_tracker(),
      cxx_dependent_scope_member_expr_rewriter.edit_tracker(),
      gmock_member_rewriter.edit_tracker(),
  };
  llvm::outs() << "==== BEGIN TRACKED EDITS ====\n";
  for (const EditTracker* edit_tracker : all_edit_trackers)
    edit_tracker->SerializeTo(llvm::outs());
  llvm::outs() << "==== END TRACKED EDITS ====\n";

  // Serialization format is documented in tools/clang/scripts/run_tool.py
  llvm::outs() << "==== BEGIN EDITS ====\n";
  for (const auto& r : replacements) {
    std::string replacement_text = r.getReplacementText().str();
    std::replace(replacement_text.begin(), replacement_text.end(), '\n', '\0');
    llvm::outs() << "r:::" << r.getFilePath() << ":::" << r.getOffset()
                 << ":::" << r.getLength() << ":::" << replacement_text << "\n";
  }
  llvm::outs() << "==== END EDITS ====\n";

  return 0;
}
