Home | History | Annotate | Download | only in rewrite_to_chrome_style
      1 // Copyright 2015 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 //
      5 // Changes Blink-style names to Chrome-style names. Currently transforms:
      6 //   fields:
      7 //     int m_operationCount => int operation_count_
      8 //   variables (including parameters):
      9 //     int mySuperVariable => int my_super_variable
     10 //   constants:
     11 //     const int maxThings => const int kMaxThings
     12 //   free functions and methods:
     13 //     void doThisThenThat() => void DoThisAndThat()
     14 
     15 #include <assert.h>
     16 #include <algorithm>
     17 #include <memory>
     18 #include <set>
     19 #include <string>
     20 
     21 #include "clang/AST/ASTContext.h"
     22 #include "clang/ASTMatchers/ASTMatchFinder.h"
     23 #include "clang/ASTMatchers/ASTMatchers.h"
     24 #include "clang/ASTMatchers/ASTMatchersMacros.h"
     25 #include "clang/Basic/CharInfo.h"
     26 #include "clang/Basic/SourceManager.h"
     27 #include "clang/Frontend/CompilerInstance.h"
     28 #include "clang/Frontend/FrontendActions.h"
     29 #include "clang/Lex/Lexer.h"
     30 #include "clang/Lex/MacroArgs.h"
     31 #include "clang/Lex/PPCallbacks.h"
     32 #include "clang/Lex/Preprocessor.h"
     33 #include "clang/Tooling/CommonOptionsParser.h"
     34 #include "clang/Tooling/Refactoring.h"
     35 #include "clang/Tooling/Tooling.h"
     36 #include "llvm/Support/CommandLine.h"
     37 #include "llvm/Support/ErrorOr.h"
     38 #include "llvm/Support/LineIterator.h"
     39 #include "llvm/Support/MemoryBuffer.h"
     40 #include "llvm/Support/Path.h"
     41 #include "llvm/Support/TargetSelect.h"
     42 
     43 #include "EditTracker.h"
     44 
     45 using namespace clang::ast_matchers;
     46 using clang::tooling::CommonOptionsParser;
     47 using clang::tooling::Replacement;
     48 using llvm::StringRef;
     49 
     50 namespace {
     51 
     52 const char kBlinkFieldPrefix[] = "m_";
     53 const char kBlinkStaticMemberPrefix[] = "s_";
     54 const char kGMockMethodNamePrefix[] = "gmock_";
     55 const char kMethodBlocklistParamName[] = "method-blocklist";
     56 
     57 std::set<clang::SourceLocation>& GetRewrittenLocs() {
     58   static auto& locations = *new std::set<clang::SourceLocation>();
     59   return locations;
     60 }
     61 
     62 template <typename MatcherType, typename NodeType>
     63 bool IsMatching(const MatcherType& matcher,
     64                 const NodeType& node,
     65                 clang::ASTContext& context) {
     66   return !match(matcher, node, context).empty();
     67 }
     68 
     69 const clang::ast_matchers::internal::
     70     VariadicDynCastAllOfMatcher<clang::Expr, clang::UnresolvedMemberExpr>
     71         unresolvedMemberExpr;
     72 
     73 const clang::ast_matchers::internal::
     74     VariadicDynCastAllOfMatcher<clang::Expr, clang::DependentScopeDeclRefExpr>
     75         dependentScopeDeclRefExpr;
     76 
     77 const clang::ast_matchers::internal::
     78     VariadicDynCastAllOfMatcher<clang::Expr, clang::CXXDependentScopeMemberExpr>
     79         cxxDependentScopeMemberExpr;
     80 
     81 AST_MATCHER(clang::FunctionDecl, isOverloadedOperator) {
     82   return Node.isOverloadedOperator();
     83 }
     84 
     85 AST_MATCHER(clang::CXXMethodDecl, isInstanceMethod) {
     86   return Node.isInstance();
     87 }
     88 
     89 AST_MATCHER_P(clang::FunctionTemplateDecl,
     90               templatedDecl,
     91               clang::ast_matchers::internal::Matcher<clang::FunctionDecl>,
     92               InnerMatcher) {
     93   return InnerMatcher.matches(*Node.getTemplatedDecl(), Finder, Builder);
     94 }
     95 
     96 AST_MATCHER_P(clang::Decl,
     97               hasCanonicalDecl,
     98               clang::ast_matchers::internal::Matcher<clang::Decl>,
     99               InnerMatcher) {
    100   return InnerMatcher.matches(*Node.getCanonicalDecl(), Finder, Builder);
    101 }
    102 
    103 // Matches a CXXMethodDecl of a method declared via MOCK_METHODx macro if such
    104 // method mocks a method matched by the InnerMatcher.  For example if "foo"
    105 // matcher matches "interfaceMethod", then mocksMethod(foo()) will match
    106 // "gmock_interfaceMethod" declared by MOCK_METHOD_x(interfaceMethod).
    107 AST_MATCHER_P(clang::CXXMethodDecl,
    108               mocksMethod,
    109               clang::ast_matchers::internal::Matcher<clang::CXXMethodDecl>,
    110               InnerMatcher) {
    111   if (!Node.getDeclName().isIdentifier())
    112     return false;
    113 
    114   llvm::StringRef method_name = Node.getName();
    115   if (!method_name.startswith(kGMockMethodNamePrefix))
    116     return false;
    117 
    118   llvm::StringRef mocked_method_name =
    119       method_name.substr(strlen(kGMockMethodNamePrefix));
    120   for (const auto& potentially_mocked_method : Node.getParent()->methods()) {
    121     clang::DeclarationName decl_name = potentially_mocked_method->getDeclName();
    122     if (!decl_name.isIdentifier() ||
    123         potentially_mocked_method->getName() != mocked_method_name)
    124       continue;
    125     if (potentially_mocked_method->getNumParams() != Node.getNumParams())
    126       continue;
    127 
    128     if (InnerMatcher.matches(*potentially_mocked_method, Finder, Builder))
    129       return true;
    130   }
    131 
    132   return false;
    133 }
    134 
    135 class MethodBlocklist {
    136  public:
    137   explicit MethodBlocklist(const std::string& filepath) {
    138     if (!filepath.empty())
    139       ParseInputFile(filepath);
    140   }
    141 
    142   bool Contains(const clang::FunctionDecl& method) const {
    143     if (!method.getDeclName().isIdentifier())
    144       return false;
    145 
    146     auto it = method_to_classes_.find(method.getName());
    147     if (it == method_to_classes_.end())
    148       return false;
    149 
    150     // |method_context| is either
    151     // 1) a CXXRecordDecl (i.e. blink::Document) or
    152     // 2) a NamespaceDecl (i.e. blink::DOMWindowTimers).
    153     const clang::NamedDecl* method_context =
    154         clang::dyn_cast<clang::NamedDecl>(method.getDeclContext());
    155     if (!method_context)
    156       return false;
    157     if (!method_context->getDeclName().isIdentifier())
    158       return false;
    159 
    160     const llvm::StringSet<>& classes = it->second;
    161     auto it2 = classes.find(method_context->getName());
    162     if (it2 == classes.end())
    163       return false;
    164 
    165     // No need to verify here that |actual_class| is in the |blink| namespace -
    166     // this will be done by other matchers elsewhere.
    167 
    168     // TODO(lukasza): Do we need to consider return type and/or param types?
    169 
    170     // TODO(lukasza): Do we need to consider param count?
    171 
    172     return true;
    173   }
    174 
    175  private:
    176   // Each line is expected to have the following format:
    177   // <class name>:::<method name>:::<number of arguments>
    178   void ParseInputFile(const std::string& filepath) {
    179     llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> file_or_err =
    180         llvm::MemoryBuffer::getFile(filepath);
    181     if (std::error_code err = file_or_err.getError()) {
    182       llvm::errs() << "ERROR: Cannot open the file specified in --"
    183                    << kMethodBlocklistParamName << " argument: " << filepath
    184                    << ": " << err.message() << "\n";
    185       assert(false);
    186       return;
    187     }
    188 
    189     llvm::line_iterator it(**file_or_err, true /* SkipBlanks */, '#');
    190     for (; !it.is_at_eof(); ++it) {
    191       llvm::StringRef line = it->trim();
    192       if (line.empty())
    193         continue;
    194 
    195       // Split the line into ':::'-delimited parts.
    196       const size_t kExpectedNumberOfParts = 3;
    197       llvm::SmallVector<llvm::StringRef, kExpectedNumberOfParts> parts;
    198       line.split(parts, ":::");
    199       if (parts.size() != kExpectedNumberOfParts) {
    200         llvm::errs() << "ERROR: Parsing error - expected "
    201                      << kExpectedNumberOfParts
    202                      << " ':::'-delimited parts: " << filepath << ":"
    203                      << it.line_number() << ": " << line << "\n";
    204         assert(false);
    205         continue;
    206       }
    207 
    208       // Parse individual parts.
    209       llvm::StringRef class_name = parts[0];
    210       llvm::StringRef method_name = parts[1];
    211       // ignoring parts[2] - the (not so trustworthy) number of parameters.
    212 
    213       // Store the new entry.
    214       method_to_classes_[method_name].insert(class_name);
    215     }
    216   }
    217 
    218   // Stores methods to blacklist in a map:
    219   // method name -> class name -> set of all allowed numbers of arguments.
    220   llvm::StringMap<llvm::StringSet<>> method_to_classes_;
    221 };
    222 
    223 AST_MATCHER_P(clang::FunctionDecl,
    224               isBlocklistedMethod,
    225               MethodBlocklist,
    226               Blocklist) {
    227   return Blocklist.Contains(Node);
    228 }
    229 
    230 // If |InnerMatcher| matches |top|, then the returned matcher will match:
    231 // - |top::function|
    232 // - |top::Class::method|
    233 // - |top::internal::Class::method|
    234 AST_MATCHER_P(
    235     clang::NestedNameSpecifier,
    236     hasTopLevelPrefix,
    237     clang::ast_matchers::internal::Matcher<clang::NestedNameSpecifier>,
    238     InnerMatcher) {
    239   const clang::NestedNameSpecifier* NodeToMatch = &Node;
    240   while (NodeToMatch->getPrefix())
    241     NodeToMatch = NodeToMatch->getPrefix();
    242   return InnerMatcher.matches(*NodeToMatch, Finder, Builder);
    243 }
    244 
    245 // This will narrow CXXCtorInitializers down for both FieldDecls and
    246 // IndirectFieldDecls (ie. anonymous unions and such). In both cases
    247 // getAnyMember() will return a FieldDecl which we can match against.
    248 AST_MATCHER_P(clang::CXXCtorInitializer,
    249               forAnyField,
    250               clang::ast_matchers::internal::Matcher<clang::FieldDecl>,
    251               InnerMatcher) {
    252   const clang::FieldDecl* NodeAsDecl = Node.getAnyMember();
    253   return (NodeAsDecl != nullptr &&
    254           InnerMatcher.matches(*NodeAsDecl, Finder, Builder));
    255 }
    256 
    257 // Matches if all the overloads in the lookup set match the provided matcher.
    258 AST_MATCHER_P(clang::OverloadExpr,
    259               allOverloadsMatch,
    260               clang::ast_matchers::internal::Matcher<clang::NamedDecl>,
    261               InnerMatcher) {
    262   if (Node.getNumDecls() == 0)
    263     return false;
    264 
    265   for (clang::NamedDecl* decl : Node.decls()) {
    266     if (!InnerMatcher.matches(*decl, Finder, Builder))
    267       return false;
    268   }
    269   return true;
    270 }
    271 
    272 void PrintForDiagnostics(clang::raw_ostream& os,
    273                          const clang::FunctionDecl& decl) {
    274   decl.getLocStart().print(os, decl.getASTContext().getSourceManager());
    275   os << ": ";
    276   decl.getNameForDiagnostic(os, decl.getASTContext().getPrintingPolicy(), true);
    277 }
    278 
    279 template <typename T>
    280 bool MatchAllOverriddenMethods(
    281     const clang::CXXMethodDecl& decl,
    282     T&& inner_matcher,
    283     clang::ast_matchers::internal::ASTMatchFinder* finder,
    284     clang::ast_matchers::internal::BoundNodesTreeBuilder* builder) {
    285   bool override_matches = false;
    286   bool override_not_matches = false;
    287 
    288   for (auto it = decl.begin_overridden_methods();
    289        it != decl.end_overridden_methods(); ++it) {
    290     if (MatchAllOverriddenMethods(**it, inner_matcher, finder, builder))
    291       override_matches = true;
    292     else
    293       override_not_matches = true;
    294   }
    295 
    296   // If this fires we have a class overriding a method that matches, and a
    297   // method that does not match the inner matcher. In that case we will match
    298   // one ancestor method but not the other. If we rename one of the and not the
    299   // other it will break what this class overrides, disconnecting it from the
    300   // one we did not rename which creates a behaviour change. So assert and
    301   // demand the user to fix the code first (or add the method to our
    302   // blacklist T_T).
    303   if (override_matches && override_not_matches) {
    304     // blink::InternalSettings::trace method overrides
    305     // 1) blink::InternalSettingsGenerated::trace
    306     //    (won't be renamed because it is in generated code)
    307     // 2) blink::Supplement<blink::Page>::trace
    308     //    (will be renamed).
    309     // It is safe to rename blink::InternalSettings::trace, because
    310     // both 1 and 2 will both be renamed (#1 via manual changes of the code
    311     // generator for DOM bindings and #2 via the clang tool).
    312     auto internal_settings_class_decl = cxxRecordDecl(
    313         hasName("InternalSettings"),
    314         hasParent(namespaceDecl(hasName("blink"),
    315                                 hasParent(translationUnitDecl()))));
    316     auto is_method_safe_to_rename = cxxMethodDecl(
    317         hasName("trace"),
    318         anyOf(hasParent(internal_settings_class_decl),  // in .h file
    319               has(nestedNameSpecifier(specifiesType(    // in .cpp file
    320                   hasDeclaration(internal_settings_class_decl))))));
    321     if (IsMatching(is_method_safe_to_rename, decl, decl.getASTContext()))
    322       return true;
    323 
    324     // For previously unknown conflicts, error out and require a human to
    325     // analyse the problem (rather than falling back to a potentially unsafe /
    326     // code semantics changing rename).
    327     llvm::errs() << "ERROR: ";
    328     PrintForDiagnostics(llvm::errs(), decl);
    329     llvm::errs() << " method overrides "
    330                  << "some virtual methods that will be automatically renamed "
    331                  << "and some that won't be renamed.";
    332     llvm::errs() << "\n";
    333     for (auto it = decl.begin_overridden_methods();
    334          it != decl.end_overridden_methods(); ++it) {
    335       if (MatchAllOverriddenMethods(**it, inner_matcher, finder, builder))
    336         llvm::errs() << "Overriden method that will be renamed: ";
    337       else
    338         llvm::errs() << "Overriden method that will not be renamed: ";
    339       PrintForDiagnostics(llvm::errs(), **it);
    340       llvm::errs() << "\n";
    341     }
    342     llvm::errs() << "\n";
    343     assert(false);
    344   }
    345 
    346   // If the method overrides something that doesn't match, so the method itself
    347   // doesn't match.
    348   if (override_not_matches)
    349     return false;
    350 
    351   // If the method overrides something that matches, so the method ifself
    352   // matches.
    353   if (override_matches)
    354     return true;
    355 
    356   return inner_matcher.matches(decl, finder, builder);
    357 }
    358 
    359 AST_MATCHER_P(clang::CXXMethodDecl,
    360               includeAllOverriddenMethods,
    361               clang::ast_matchers::internal::Matcher<clang::CXXMethodDecl>,
    362               InnerMatcher) {
    363   return MatchAllOverriddenMethods(Node, InnerMatcher, Finder, Builder);
    364 }
    365 
    366 // Matches |T::m| and/or |x->T::m| and/or |x->m| CXXDependentScopeMemberExpr
    367 // if member |m| comes from a type that matches the InnerMatcher.
    368 AST_MATCHER_P(clang::CXXDependentScopeMemberExpr,
    369               hasMemberFromType,
    370               clang::ast_matchers::internal::Matcher<clang::QualType>,
    371               InnerMatcher) {
    372   // Given |T::m| and/or |x->T::m| and/or |x->m| ...
    373   if (clang::NestedNameSpecifier* nestedNameSpecifier = Node.getQualifier()) {
    374     // ... if |T| is present, then InnerMatcher has to match |T|.
    375     clang::QualType qualType(nestedNameSpecifier->getAsType(), 0);
    376     return InnerMatcher.matches(qualType, Finder, Builder);
    377   } else {
    378     // ... if there is no |T|, then InnerMatcher has to match the type of |x|.
    379     clang::Expr* base_expr = Node.isImplicitAccess() ? nullptr : Node.getBase();
    380     return base_expr &&
    381            InnerMatcher.matches(base_expr->getType(), Finder, Builder);
    382   }
    383 }
    384 
    385 // Matches |const Class<T>&| QualType if InnerMatcher matches |Class<T>|.
    386 AST_MATCHER_P(clang::QualType,
    387               hasBaseType,
    388               clang::ast_matchers::internal::Matcher<clang::Type>,
    389               InnerMatcher) {
    390   const clang::Type* type = Node.getTypePtrOrNull();
    391   return type && InnerMatcher.matches(*type, Finder, Builder);
    392 }
    393 
    394 bool IsMethodOverrideOf(const clang::CXXMethodDecl& decl,
    395                         const char* class_name) {
    396   if (decl.getParent()->getQualifiedNameAsString() == class_name)
    397     return true;
    398   for (auto it = decl.begin_overridden_methods();
    399        it != decl.end_overridden_methods(); ++it) {
    400     if (IsMethodOverrideOf(**it, class_name))
    401       return true;
    402   }
    403   return false;
    404 }
    405 
    406 bool IsBlacklistedFunctionName(llvm::StringRef name) {
    407   // https://crbug.com/672902: Method names with an underscore are typically
    408   // mimicked after std library / are typically not originating from Blink.
    409   // Do not rewrite such names (like push_back, emplace_back, etc.).
    410   if (name.find('_') != llvm::StringRef::npos)
    411     return true;
    412 
    413   return false;
    414 }
    415 
    416 bool IsBlacklistedFreeFunctionName(llvm::StringRef name) {
    417   // swap() functions should match the signature of std::swap for ADL tricks.
    418   return name == "swap";
    419 }
    420 
    421 bool IsBlacklistedInstanceMethodName(llvm::StringRef name) {
    422   static const char* kBlacklistedNames[] = {
    423       // We should avoid renaming the method names listed below, because
    424       // 1. They are used in templated code (e.g. in <algorithms>)
    425       // 2. They (begin+end) are used in range-based for syntax sugar
    426       //    - for (auto x : foo) { ... }  // <- foo.begin() will be called.
    427       "begin", "end", "rbegin", "rend", "lock", "unlock", "try_lock",
    428 
    429       // https://crbug.com/672902: Should not rewrite names that mimick methods
    430       // from std library.
    431       "at", "back", "empty", "erase", "front", "insert", "length", "size",
    432   };
    433   for (const auto& b : kBlacklistedNames) {
    434     if (name == b)
    435       return true;
    436   }
    437   return false;
    438 }
    439 
    440 bool IsBlacklistedMethodName(llvm::StringRef name) {
    441   return IsBlacklistedFunctionName(name) ||
    442          IsBlacklistedInstanceMethodName(name);
    443 }
    444 
    445 bool IsBlacklistedFunction(const clang::FunctionDecl& decl) {
    446   if (!decl.getDeclName().isIdentifier())
    447     return false;
    448 
    449   clang::StringRef name = decl.getName();
    450   return IsBlacklistedFunctionName(name) || IsBlacklistedFreeFunctionName(name);
    451 }
    452 
    453 bool IsBlacklistedMethod(const clang::CXXMethodDecl& decl) {
    454   if (!decl.getDeclName().isIdentifier())
    455     return false;
    456 
    457   clang::StringRef name = decl.getName();
    458   if (IsBlacklistedFunctionName(name))
    459     return true;
    460 
    461   // Remaining cases are only applicable to instance methods.
    462   if (decl.isStatic())
    463     return false;
    464 
    465   if (IsBlacklistedInstanceMethodName(name))
    466     return true;
    467 
    468   // Subclasses of InspectorAgent will subclass "disable()" from both blink and
    469   // from gen/, which is problematic, but DevTools folks don't want to rename
    470   // it or split this up. So don't rename it at all.
    471   if (name.equals("disable") &&
    472       IsMethodOverrideOf(decl, "blink::InspectorBaseAgent"))
    473     return true;
    474 
    475   return false;
    476 }
    477 
    478 AST_MATCHER(clang::FunctionDecl, isBlacklistedFunction) {
    479   return IsBlacklistedFunction(Node);
    480 }
    481 
    482 AST_MATCHER(clang::CXXMethodDecl, isBlacklistedMethod) {
    483   return IsBlacklistedMethod(Node);
    484 }
    485 
    486 bool IsKnownTraitName(clang::StringRef name) {
    487   // This set of names is globally a type trait throughout chromium.
    488   return name == "safeToCompareToEmptyOrDeleted";
    489 }
    490 
    491 AST_MATCHER(clang::VarDecl, isKnownTraitName) {
    492   return Node.getDeclName().isIdentifier() && IsKnownTraitName(Node.getName());
    493 }
    494 
    495 AST_MATCHER(clang::Decl, isDeclInGeneratedFile) {
    496   // This matcher mimics the built-in isExpansionInFileMatching matcher from
    497   // llvm/tools/clang/include/clang/ASTMatchers/ASTMatchers.h, except:
    498   // - It special cases some files (e.g. doesn't skip renaming of identifiers
    499   //   from gen/blink/core/ComputedStyleBase.h)
    500 
    501   const clang::SourceManager& source_manager =
    502       Node.getASTContext().getSourceManager();
    503 
    504   // TODO(lukasza): Consider using getSpellingLoc below.
    505   // The built-in isExpansionInFileMatching matcher uses getExpansionLoc below.
    506   // We could consider using getSpellingLoc (which properly handles things like
    507   // SETTINGS_GETTERS_AND_SETTERS macro which is defined in generated code
    508   // (gen/blink/core/SettingsMacros.h), but expanded in non-generated code
    509   // (third_party/WebKit/Source/core/frame/Settings.h).
    510   clang::SourceLocation loc =
    511       source_manager.getExpansionLoc(Node.getLocStart());
    512 
    513   // TODO(lukasza): jump out of scratch space if token concatenation was used.
    514   if (loc.isInvalid())
    515     return false;
    516 
    517   const clang::FileEntry* file_entry =
    518       source_manager.getFileEntryForID(source_manager.getFileID(loc));
    519   if (!file_entry)
    520     return false;
    521 
    522   bool is_generated_file = false;
    523   bool is_computed_style_base_cpp =
    524       llvm::sys::path::filename(file_entry->getName())
    525           .equals("ComputedStyleBase.h");
    526   for (auto it = llvm::sys::path::begin(file_entry->getName());
    527        it != llvm::sys::path::end(file_entry->getName()); ++it) {
    528     if (it->equals("gen")) {
    529       is_generated_file = true;
    530       break;
    531     }
    532   }
    533   // ComputedStyleBase is intentionally not treated as a generated file, since
    534   // style definitions are split between generated and non-generated code. It's
    535   // easier to have the tool just automatically rewrite references to generated
    536   // code as well, with a small manual patch to fix the code generators.
    537   return is_generated_file && !is_computed_style_base_cpp;
    538 }
    539 
    540 // Helper to convert from a camelCaseName to camel_case_name. It uses some
    541 // heuristics to try to handle acronyms in camel case names correctly.
    542 std::string CamelCaseToUnderscoreCase(StringRef input) {
    543   std::string output;
    544   bool needs_underscore = false;
    545   bool was_lowercase = false;
    546   bool was_uppercase = false;
    547   bool first_char = true;
    548   // Iterate in reverse to minimize the amount of backtracking.
    549   for (const unsigned char* i = input.bytes_end() - 1; i >= input.bytes_begin();
    550        --i) {
    551     char c = *i;
    552     bool is_lowercase = clang::isLowercase(c);
    553     bool is_uppercase = clang::isUppercase(c);
    554     c = clang::toLowercase(c);
    555     // Transitioning from upper to lower case requires an underscore. This is
    556     // needed to handle names with acronyms, e.g. handledHTTPRequest needs a '_'
    557     // in 'dH'. This is a complement to the non-acronym case further down.
    558     if (was_uppercase && is_lowercase)
    559       needs_underscore = true;
    560     if (needs_underscore) {
    561       output += '_';
    562       needs_underscore = false;
    563     }
    564     output += c;
    565     // Handles the non-acronym case: transitioning from lower to upper case
    566     // requires an underscore when emitting the next character, e.g. didLoad
    567     // needs a '_' in 'dL'.
    568     if (!first_char && was_lowercase && is_uppercase)
    569       needs_underscore = true;
    570     was_lowercase = is_lowercase;
    571     was_uppercase = is_uppercase;
    572     first_char = false;
    573   }
    574   std::reverse(output.begin(), output.end());
    575   return output;
    576 }
    577 
    578 bool CanBeEvaluatedAtCompileTime(const clang::Stmt* stmt,
    579                                  const clang::ASTContext& context) {
    580   auto* expr = clang::dyn_cast<clang::Expr>(stmt);
    581   if (!expr) {
    582     // If the statement is not an expression then it's a constant.
    583     return true;
    584   }
    585 
    586   // Function calls create non-consistent behaviour. For some template
    587   // instantiations they can be constexpr while for others they are not, which
    588   // changes the output of isEvaluatable().
    589   if (expr->hasNonTrivialCall(context))
    590     return false;
    591 
    592   // Recurse on children. If they are all const (or are uses of template
    593   // input) then the statement can be considered const. For whatever reason the
    594   // below checks can give different-and-less-consistent responses if we call
    595   // them on a complex expression than if we call them on the most primitive
    596   // pieces (some pieces would say false but the whole thing says true).
    597   for (auto* child : expr->children()) {
    598     if (!CanBeEvaluatedAtCompileTime(child, context))
    599       return false;
    600   }
    601 
    602   // If the expression depends on template input, we can not call
    603   // isEvaluatable() on it as it will do bad things/crash.
    604   if (!expr->isInstantiationDependent()) {
    605     // If the expression can be evaluated at compile time, then it should have a
    606     // kFoo style name. Otherwise, not.
    607     return expr->isEvaluatable(context);
    608   }
    609 
    610   // We do our best to figure out special cases as we come across them here, for
    611   // template dependent situations. Some cases in code are only considered
    612   // instantiation dependent for some template instantiations! Which is
    613   // terrible! So most importantly we try to match isEvaluatable in those cases.
    614   switch (expr->getStmtClass()) {
    615     case clang::Stmt::CXXThisExprClass:
    616       return false;
    617     case clang::Stmt::DeclRefExprClass: {
    618       auto* declref = clang::dyn_cast<clang::DeclRefExpr>(expr);
    619       auto* decl = declref->getDecl();
    620       if (auto* vardecl = clang::dyn_cast<clang::VarDecl>(decl)) {
    621         if (auto* initializer = vardecl->getInit())
    622           return CanBeEvaluatedAtCompileTime(initializer, context);
    623         return false;
    624       }
    625       break;
    626     }
    627 
    628     default:
    629       break;
    630   }
    631 
    632   // Otherwise, we consider depending on template parameters to not interfere
    633   // with being const.. with exceptions hopefully covered above.
    634   return true;
    635 }
    636 
    637 bool IsProbablyConst(const clang::VarDecl& decl,
    638                      const clang::ASTContext& context) {
    639   clang::QualType type = decl.getType();
    640   if (!type.isConstQualified())
    641     return false;
    642 
    643   if (type.isVolatileQualified())
    644     return false;
    645 
    646   if (decl.isConstexpr())
    647     return true;
    648 
    649   // Parameters should not be renamed to |kFooBar| style (even if they are
    650   // const and have an initializer (aka default value)).
    651   if (clang::isa<clang::ParmVarDecl>(&decl))
    652     return false;
    653 
    654   // http://google.github.io/styleguide/cppguide.html#Constant_Names
    655   // Static variables that are const-qualified should use kConstantStyle naming.
    656   if (decl.getStorageDuration() == clang::SD_Static)
    657     return true;
    658 
    659   const clang::Expr* initializer = decl.getInit();
    660   if (!initializer)
    661     return false;
    662 
    663   return CanBeEvaluatedAtCompileTime(initializer, context);
    664 }
    665 
    666 AST_MATCHER_P(clang::QualType, hasString, std::string, ExpectedString) {
    667   return ExpectedString == Node.getAsString();
    668 }
    669 
    670 bool ShouldPrefixFunctionName(const std::string& old_method_name) {
    671   // Functions that are named similarily to a type - they should be prefixed
    672   // with a "Get" prefix.
    673   static const char* kConflictingMethods[] = {"accumulatorMap",
    674                                               "animationWorklet",
    675                                               "attrNodeList",
    676                                               "audioWorklet",
    677                                               "binaryType",
    678                                               "blob",
    679                                               "channelCountMode",
    680                                               "color",
    681                                               "compositorElementId",
    682                                               "constructionStack",
    683                                               "controlSize",
    684                                               "counterDirectives",
    685                                               "counterMaps",
    686                                               "document",
    687                                               "dragOperation",
    688                                               "element",
    689                                               "emptyChromeClient",
    690                                               "emptyEditorClient",
    691                                               "emptySpellCheckerClient",
    692                                               "entryType",
    693                                               "error",
    694                                               "eventTargetDataMap",
    695                                               "fileUtilities",
    696                                               "font",
    697                                               "frame",
    698                                               "frameBlameContext",
    699                                               "frontend",
    700                                               "gridCell",
    701                                               "harfBuzzFontCache",
    702                                               "hash",
    703                                               "heapObjectHeader",
    704                                               "heapObjectSet",
    705                                               "iconURL",
    706                                               "image",
    707                                               "infoMap",
    708                                               "inputMethodController",
    709                                               "inputType",
    710                                               "interpolationTypes",
    711                                               "intervalArena",
    712                                               "layout",
    713                                               "layoutBlock",
    714                                               "layoutObject",
    715                                               "layoutSize",
    716                                               "lineCap",
    717                                               "lineEndings",
    718                                               "lineJoin",
    719                                               "listItems",
    720                                               "locationInBackingMap",
    721                                               "matchedProperties",
    722                                               "midpointState",
    723                                               "modifiers",
    724                                               "mouseEvent",
    725                                               "name",
    726                                               "navigationType",
    727                                               "node",
    728                                               "notificationManager",
    729                                               "originAccessMap",
    730                                               "outcome",
    731                                               "pagePopup",
    732                                               "paintWorklet",
    733                                               "path",
    734                                               "position",
    735                                               "presentationAttributeCache",
    736                                               "processingInstruction",
    737                                               "qualifiedNameCache",
    738                                               "readyState",
    739                                               "referrer",
    740                                               "referrerPolicy",
    741                                               "relList",
    742                                               "resource",
    743                                               "response",
    744                                               "restrictedKeyMap",
    745                                               "sandboxSupport",
    746                                               "screenInfo",
    747                                               "screenOrientationController",
    748                                               "scrollAnimator",
    749                                               "scrollbarPainterMap",
    750                                               "scrollbarSet",
    751                                               "selectionInDOMTree",
    752                                               "selectionInFlatTree",
    753                                               "selectionVisualRectMap",
    754                                               "selectorTextCache",
    755                                               "settings",
    756                                               "shadowRootType",
    757                                               "signalingState",
    758                                               "snapshotById",
    759                                               "state",
    760                                               "stickyConstraintsMap",
    761                                               "string",
    762                                               "styleSharingList",
    763                                               "styleSheet",
    764                                               "supplementable",
    765                                               "text",
    766                                               "textAlign",
    767                                               "textBaseline",
    768                                               "textDirection",
    769                                               "theme",
    770                                               "thread",
    771                                               "timing",
    772                                               "topLevelBlameContext",
    773                                               "type",
    774                                               "vector",
    775                                               "visibleSelection",
    776                                               "visibleSelectionInFlatTree",
    777                                               "weakHeapObjectSet",
    778                                               "webFrame",
    779                                               "widget",
    780                                               "wordBoundaries",
    781                                               "workerThread",
    782                                               "worldId",
    783                                               "worldMap",
    784                                               "wrapperTypeInfo"};
    785   for (const auto& conflicting_method : kConflictingMethods) {
    786     if (old_method_name == conflicting_method)
    787       return true;
    788   }
    789 
    790   return false;
    791 }
    792 
    793 AST_MATCHER(clang::FunctionDecl, shouldPrefixFunctionName) {
    794   return Node.getDeclName().isIdentifier() &&
    795       ShouldPrefixFunctionName(Node.getName().str());
    796 }
    797 
    798 bool GetNameForDecl(const clang::FunctionDecl& decl,
    799                     clang::ASTContext& context,
    800                     std::string& name) {
    801   name = decl.getName().str();
    802   name[0] = clang::toUppercase(name[0]);
    803 
    804   // Given
    805   //   class Foo {};
    806   //   class DerivedFoo : class Foo;
    807   //   using Bar = Foo;
    808   //   Bar f1();  // <- |Bar| would be matched by hasString("Bar") below.
    809   //   Bar f2();  // <- |Bar| would be matched by hasName("Foo") below.
    810   //   DerivedFoo f3();  // <- |DerivedFoo| matched by isDerivedFrom(...) below.
    811   // |type_with_same_name_as_function| matcher matches Bar and Foo return types.
    812   auto type_with_same_name_as_function = qualType(anyOf(
    813       // hasString matches the type as spelled (Bar above).
    814       hasString(name),
    815       // hasDeclaration matches resolved type (Foo or DerivedFoo above).
    816       hasDeclaration(namedDecl(hasName(name)))));
    817 
    818   // |type_containing_same_name_as_function| matcher will match all of the
    819   // return types below:
    820   // - Foo foo()  // Direct application of |type_with_same_name_as_function|.
    821   // - Foo* foo()  // |hasDescendant| traverses references/pointers.
    822   // - RefPtr<Foo> foo()  // |hasDescendant| traverses template arguments.
    823   auto type_containing_same_name_as_function =
    824       qualType(anyOf(type_with_same_name_as_function,
    825                      hasDescendant(type_with_same_name_as_function)));
    826   // https://crbug.com/582312: Prepend "Get" if method name conflicts with
    827   // return type.
    828   auto conflict_matcher = functionDecl(anyOf(
    829       // For functions and non-virtual or base method implementations just
    830       // compare with the immediate return type.
    831       functionDecl(returns(type_containing_same_name_as_function),
    832                    unless(cxxMethodDecl(isOverride()))),
    833       // For methods that override one or more methods, compare with the return
    834       // type of the *base* methods.
    835       cxxMethodDecl(isOverride(), forEachOverridden(returns(
    836                                       type_containing_same_name_as_function))),
    837       // And also check hardcoded list of function names to prefix with "Get".
    838       shouldPrefixFunctionName()));
    839   if (IsMatching(conflict_matcher, decl, context))
    840     name = "Get" + name;
    841 
    842   return true;
    843 }
    844 
    845 bool GetNameForDecl(const clang::EnumConstantDecl& decl,
    846                     clang::ASTContext& context,
    847                     std::string& name) {
    848   StringRef original_name = decl.getName();
    849 
    850   // If it's already correct leave it alone.
    851   if (original_name.size() >= 2 && original_name[0] == 'k' &&
    852       clang::isUppercase(original_name[1]))
    853     return false;
    854 
    855   bool is_shouty = true;
    856   for (char c : original_name) {
    857     if (!clang::isUppercase(c) && !clang::isDigit(c) && c != '_') {
    858       is_shouty = false;
    859       break;
    860     }
    861   }
    862 
    863   if (is_shouty)
    864     return false;
    865 
    866   name = 'k';  // k prefix on enum values.
    867   name += original_name;
    868   name[1] = clang::toUppercase(name[1]);
    869   return true;
    870 }
    871 
    872 bool GetNameForDecl(const clang::FieldDecl& decl,
    873                     clang::ASTContext& context,
    874                     std::string& name) {
    875   StringRef original_name = decl.getName();
    876   bool member_prefix = original_name.startswith(kBlinkFieldPrefix);
    877 
    878   StringRef rename_part = !member_prefix
    879                               ? original_name
    880                               : original_name.substr(strlen(kBlinkFieldPrefix));
    881   name = CamelCaseToUnderscoreCase(rename_part);
    882 
    883   // Assume that prefix of m_ was intentional and always replace it with a
    884   // suffix _.
    885   if (member_prefix && name.back() != '_')
    886     name += '_';
    887 
    888   return true;
    889 }
    890 
    891 bool GetNameForDecl(const clang::VarDecl& decl,
    892                     clang::ASTContext& context,
    893                     std::string& name) {
    894   StringRef original_name = decl.getName();
    895 
    896   // Nothing to do for unnamed parameters.
    897   if (clang::isa<clang::ParmVarDecl>(decl) && original_name.empty())
    898     return false;
    899 
    900   // This is a type trait that appears in consumers of WTF as well as inside
    901   // WTF. We want it to be named in this_style_of_case accordingly.
    902   if (IsKnownTraitName(original_name)) {
    903     name = CamelCaseToUnderscoreCase(original_name);
    904     return true;
    905   }
    906 
    907   // static class members match against VarDecls. Blink style dictates that
    908   // these should be prefixed with `s_`, so strip that off. Also check for `m_`
    909   // and strip that off too, for code that accidentally uses the wrong prefix.
    910   if (original_name.startswith(kBlinkStaticMemberPrefix))
    911     original_name = original_name.substr(strlen(kBlinkStaticMemberPrefix));
    912   else if (original_name.startswith(kBlinkFieldPrefix))
    913     original_name = original_name.substr(strlen(kBlinkFieldPrefix));
    914 
    915   bool is_const = IsProbablyConst(decl, context);
    916   if (is_const) {
    917     // Don't try to rename constants that already conform to Chrome style.
    918     if (original_name.size() >= 2 && original_name[0] == 'k' &&
    919         clang::isUppercase(original_name[1]))
    920       return false;
    921     // Or names are spelt with underscore casing. While they are actually
    922     // compile consts, the author wrote it explicitly as a variable not as
    923     // a constant (they would have used kFormat otherwise here), so preserve
    924     // it rather than try to mangle a kFormat out of it.
    925     if (original_name.find('_') != StringRef::npos)
    926       return false;
    927 
    928     name = 'k';
    929     name.append(original_name.data(), original_name.size());
    930     name[1] = clang::toUppercase(name[1]);
    931   } else {
    932     name = CamelCaseToUnderscoreCase(original_name);
    933 
    934     // Non-const variables with static storage duration at namespace scope are
    935     // prefixed with `g_' to reduce the likelihood of a naming collision.
    936     const clang::DeclContext* decl_context = decl.getDeclContext();
    937     if (name.find("g_") != 0 && decl.hasGlobalStorage() &&
    938         decl_context->isNamespace())
    939       name.insert(0, "g_");
    940   }
    941 
    942   // Static members end with _ just like other members, but constants should
    943   // not.
    944   if (!is_const && decl.isStaticDataMember()) {
    945     name += '_';
    946   }
    947 
    948   return true;
    949 }
    950 
    951 bool GetNameForDecl(const clang::FunctionTemplateDecl& decl,
    952                     clang::ASTContext& context,
    953                     std::string& name) {
    954   clang::FunctionDecl* templated_function = decl.getTemplatedDecl();
    955   return GetNameForDecl(*templated_function, context, name);
    956 }
    957 
    958 bool GetNameForDecl(const clang::NamedDecl& decl,
    959                     clang::ASTContext& context,
    960                     std::string& name) {
    961   if (auto* function = clang::dyn_cast<clang::FunctionDecl>(&decl))
    962     return GetNameForDecl(*function, context, name);
    963   if (auto* var = clang::dyn_cast<clang::VarDecl>(&decl))
    964     return GetNameForDecl(*var, context, name);
    965   if (auto* field = clang::dyn_cast<clang::FieldDecl>(&decl))
    966     return GetNameForDecl(*field, context, name);
    967   if (auto* function_template =
    968           clang::dyn_cast<clang::FunctionTemplateDecl>(&decl))
    969     return GetNameForDecl(*function_template, context, name);
    970   if (auto* enumc = clang::dyn_cast<clang::EnumConstantDecl>(&decl))
    971     return GetNameForDecl(*enumc, context, name);
    972 
    973   return false;
    974 }
    975 
    976 bool GetNameForDecl(const clang::UsingDecl& decl,
    977                     clang::ASTContext& context,
    978                     std::string& name) {
    979   assert(decl.shadow_size() > 0);
    980 
    981   // If a using declaration's targeted declaration is a set of overloaded
    982   // functions, it can introduce multiple shadowed declarations. Just using the
    983   // first one is OK, since overloaded functions have the same name, by
    984   // definition.
    985   return GetNameForDecl(*decl.shadow_begin()->getTargetDecl(), context, name);
    986 }
    987 
    988 template <typename Type>
    989 struct TargetNodeTraits;
    990 
    991 template <>
    992 struct TargetNodeTraits<clang::NamedDecl> {
    993   static clang::SourceLocation GetLoc(const clang::NamedDecl& decl) {
    994     return decl.getLocation();
    995   }
    996   static const char* GetName() { return "decl"; }
    997   static const char* GetType() { return "NamedDecl"; }
    998 };
    999 
   1000 template <>
   1001 struct TargetNodeTraits<clang::MemberExpr> {
   1002   static clang::SourceLocation GetLoc(const clang::MemberExpr& expr) {
   1003     return expr.getMemberLoc();
   1004   }
   1005   static const char* GetName() { return "expr"; }
   1006   static const char* GetType() { return "MemberExpr"; }
   1007 };
   1008 
   1009 template <>
   1010 struct TargetNodeTraits<clang::DeclRefExpr> {
   1011   static clang::SourceLocation GetLoc(const clang::DeclRefExpr& expr) {
   1012     return expr.getLocation();
   1013   }
   1014   static const char* GetName() { return "expr"; }
   1015   static const char* GetType() { return "DeclRefExpr"; }
   1016 };
   1017 
   1018 template <>
   1019 struct TargetNodeTraits<clang::DependentScopeDeclRefExpr> {
   1020   static clang::SourceLocation GetLoc(
   1021       const clang::DependentScopeDeclRefExpr& expr) {
   1022     return expr.getLocation();
   1023   }
   1024   static const char* GetName() { return "expr"; }
   1025 };
   1026 
   1027 template <>
   1028 struct TargetNodeTraits<clang::CXXDependentScopeMemberExpr> {
   1029   static clang::SourceLocation GetLoc(
   1030       const clang::CXXDependentScopeMemberExpr& expr) {
   1031     return expr.getMemberLoc();
   1032   }
   1033   static const char* GetName() { return "expr"; }
   1034 };
   1035 
   1036 template <>
   1037 struct TargetNodeTraits<clang::CXXCtorInitializer> {
   1038   static clang::SourceLocation GetLoc(const clang::CXXCtorInitializer& init) {
   1039     assert(init.isWritten());
   1040     return init.getSourceLocation();
   1041   }
   1042   static const char* GetName() { return "initializer"; }
   1043   static const char* GetType() { return "CXXCtorInitializer"; }
   1044 };
   1045 
   1046 template <>
   1047 struct TargetNodeTraits<clang::UnresolvedLookupExpr> {
   1048   static clang::SourceLocation GetLoc(const clang::UnresolvedLookupExpr& expr) {
   1049     return expr.getNameLoc();
   1050   }
   1051   static const char* GetName() { return "expr"; }
   1052   static const char* GetType() { return "UnresolvedLookupExpr"; }
   1053 };
   1054 
   1055 template <>
   1056 struct TargetNodeTraits<clang::UnresolvedMemberExpr> {
   1057   static clang::SourceLocation GetLoc(const clang::UnresolvedMemberExpr& expr) {
   1058     return expr.getMemberLoc();
   1059   }
   1060   static const char* GetName() { return "expr"; }
   1061   static const char* GetType() { return "UnresolvedMemberExpr"; }
   1062 };
   1063 
   1064 template <>
   1065 struct TargetNodeTraits<clang::UnresolvedUsingValueDecl> {
   1066   static clang::SourceLocation GetLoc(
   1067       const clang::UnresolvedUsingValueDecl& decl) {
   1068     return decl.getNameInfo().getLoc();
   1069   }
   1070   static const char* GetName() { return "decl"; }
   1071   static const char* GetType() { return "UnresolvedUsingValueDecl"; }
   1072 };
   1073 
   1074 template <typename TargetNode>
   1075 class RewriterBase : public MatchFinder::MatchCallback {
   1076  public:
   1077   explicit RewriterBase(std::set<Replacement>* replacements,
   1078                         RenameCategory category)
   1079       : replacements_(replacements), edit_tracker_(category) {}
   1080 
   1081   const TargetNode& GetTargetNode(const MatchFinder::MatchResult& result) {
   1082     const TargetNode* target_node = result.Nodes.getNodeAs<TargetNode>(
   1083         TargetNodeTraits<TargetNode>::GetName());
   1084     assert(target_node);
   1085     return *target_node;
   1086   }
   1087 
   1088   bool GenerateReplacement(const MatchFinder::MatchResult& result,
   1089                            clang::SourceLocation loc,
   1090                            llvm::StringRef old_name,
   1091                            std::string new_name,
   1092                            Replacement* replacement) {
   1093     const clang::ASTContext& context = *result.Context;
   1094     const clang::SourceManager& source_manager = *result.SourceManager;
   1095 
   1096     if (loc.isMacroID()) {
   1097       // Try to jump "above" the scratch buffer if |loc| is inside
   1098       // token##Concatenation.
   1099       const int kMaxJumps = 5;
   1100       bool verified_out_of_scratch_space = false;
   1101       for (int i = 0; i < kMaxJumps && !verified_out_of_scratch_space; i++) {
   1102         clang::SourceLocation spell = source_manager.getSpellingLoc(loc);
   1103         verified_out_of_scratch_space =
   1104             source_manager.getBufferName(spell) != "<scratch space>";
   1105         if (!verified_out_of_scratch_space)
   1106           loc = source_manager.getImmediateMacroCallerLoc(loc);
   1107       }
   1108       if (!verified_out_of_scratch_space)
   1109         return false;
   1110     }
   1111 
   1112     // If the edit affects only the first character of the identifier, then
   1113     // narrow down the edit to only this single character.  This is important
   1114     // for dealing with toFooBar -> ToFooBar method renaming when the method
   1115     // name is built using macro token concatenation like to##macroArgument - in
   1116     // this case we should only rewrite "t" -> "T" and leave "o##macroArgument"
   1117     // untouched.
   1118     llvm::StringRef expected_old_text = old_name;
   1119     llvm::StringRef new_text = new_name;
   1120     if (loc.isMacroID() && expected_old_text.substr(1) == new_text.substr(1)) {
   1121       expected_old_text = expected_old_text.substr(0, 1);
   1122       new_text = new_text.substr(0, 1);
   1123     }
   1124     clang::SourceLocation spell = source_manager.getSpellingLoc(loc);
   1125     clang::CharSourceRange range = clang::CharSourceRange::getCharRange(
   1126         spell, spell.getLocWithOffset(expected_old_text.size()));
   1127 
   1128     // We need to ensure that |actual_old_text| is the same as
   1129     // |expected_old_text| - it can be different if |actual_old_text| contains
   1130     // a macro argument (see DEFINE_WITH_TOKEN_CONCATENATION2 in
   1131     // macros-original.cc testcase).
   1132     StringRef actual_old_text = clang::Lexer::getSourceText(
   1133         range, source_manager, context.getLangOpts());
   1134     if (actual_old_text != expected_old_text)
   1135       return false;
   1136 
   1137     if (replacement) {
   1138       // If there's already a replacement for this location, don't emit any
   1139       // other replacements to avoid potential naming conflicts. This is
   1140       // primarily to avoid problems when a function and a parameter are defined
   1141       // by the same macro argument.
   1142       if (!GetRewrittenLocs().emplace(spell).second)
   1143         return false;
   1144 
   1145       *replacement = Replacement(source_manager, range, new_text);
   1146     }
   1147     return true;
   1148   }
   1149 
   1150   virtual clang::SourceLocation GetTargetLoc(
   1151       const MatchFinder::MatchResult& result) {
   1152     return TargetNodeTraits<TargetNode>::GetLoc(GetTargetNode(result));
   1153   }
   1154 
   1155   void AddReplacement(const MatchFinder::MatchResult& result,
   1156                       llvm::StringRef old_name,
   1157                       std::string new_name) {
   1158     if (old_name == new_name)
   1159       return;
   1160 
   1161     clang::SourceLocation loc = GetTargetLoc(result);
   1162     if (loc.isInvalid())
   1163       return;
   1164 
   1165     Replacement replacement;
   1166     if (!GenerateReplacement(result, loc, old_name, new_name, &replacement))
   1167       return;
   1168 
   1169     replacements_->insert(std::move(replacement));
   1170     edit_tracker_.Add(*result.SourceManager, loc, old_name, new_name);
   1171   }
   1172 
   1173   const EditTracker* edit_tracker() const { return &edit_tracker_; }
   1174 
   1175  private:
   1176   std::set<Replacement>* const replacements_;
   1177   EditTracker edit_tracker_;
   1178 };
   1179 
   1180 template <typename DeclNode>
   1181 RenameCategory GetCategory();
   1182 template <>
   1183 RenameCategory GetCategory<clang::FieldDecl>() {
   1184   return RenameCategory::kField;
   1185 }
   1186 template <>
   1187 RenameCategory GetCategory<clang::VarDecl>() {
   1188   return RenameCategory::kVariable;
   1189 }
   1190 template <>
   1191 RenameCategory GetCategory<clang::FunctionDecl>() {
   1192   return RenameCategory::kFunction;
   1193 }
   1194 template <>
   1195 RenameCategory GetCategory<clang::CXXMethodDecl>() {
   1196   return RenameCategory::kFunction;
   1197 }
   1198 template <>
   1199 RenameCategory GetCategory<clang::EnumConstantDecl>() {
   1200   return RenameCategory::kEnumValue;
   1201 }
   1202 template <>
   1203 RenameCategory GetCategory<clang::NamedDecl>() {
   1204   return RenameCategory::kUnresolved;
   1205 }
   1206 template <>
   1207 RenameCategory GetCategory<clang::UsingDecl>() {
   1208   return RenameCategory::kUnresolved;
   1209 }
   1210 
   1211 template <typename DeclNode, typename TargetNode>
   1212 class DeclRewriterBase : public RewriterBase<TargetNode> {
   1213  public:
   1214   using Base = RewriterBase<TargetNode>;
   1215 
   1216   explicit DeclRewriterBase(std::set<Replacement>* replacements)
   1217       : Base(replacements, GetCategory<DeclNode>()) {}
   1218 
   1219   void run(const MatchFinder::MatchResult& result) override {
   1220     const DeclNode* decl = result.Nodes.getNodeAs<DeclNode>("decl");
   1221     if (!decl->getDeclName().isIdentifier())
   1222       return;
   1223 
   1224     assert(decl);
   1225     llvm::StringRef old_name = decl->getName();
   1226 
   1227     // Return early if there's no name to be renamed.
   1228     if (!decl->getIdentifier())
   1229       return;
   1230 
   1231     // Get the new name.
   1232     std::string new_name;
   1233     if (!GetNameForDecl(*decl, *result.Context, new_name))
   1234       return;  // If false, the name was not suitable for renaming.
   1235 
   1236     // Check if we are able to rewrite the decl (to avoid rewriting if the
   1237     // decl's identifier is part of macro##Token##Concatenation).
   1238     clang::SourceLocation decl_loc =
   1239         TargetNodeTraits<clang::NamedDecl>::GetLoc(*decl);
   1240     if (!Base::GenerateReplacement(result, decl_loc, old_name, new_name,
   1241                                    nullptr))
   1242       return;
   1243 
   1244     Base::AddReplacement(result, old_name, std::move(new_name));
   1245   }
   1246 };
   1247 
   1248 using FieldDeclRewriter = DeclRewriterBase<clang::FieldDecl, clang::NamedDecl>;
   1249 using VarDeclRewriter = DeclRewriterBase<clang::VarDecl, clang::NamedDecl>;
   1250 using MemberRewriter = DeclRewriterBase<clang::FieldDecl, clang::MemberExpr>;
   1251 using DeclRefRewriter = DeclRewriterBase<clang::VarDecl, clang::DeclRefExpr>;
   1252 using FieldDeclRefRewriter =
   1253     DeclRewriterBase<clang::FieldDecl, clang::DeclRefExpr>;
   1254 using FunctionDeclRewriter =
   1255     DeclRewriterBase<clang::FunctionDecl, clang::NamedDecl>;
   1256 using FunctionRefRewriter =
   1257     DeclRewriterBase<clang::FunctionDecl, clang::DeclRefExpr>;
   1258 using ConstructorInitializerRewriter =
   1259     DeclRewriterBase<clang::FieldDecl, clang::CXXCtorInitializer>;
   1260 
   1261 using MethodDeclRewriter =
   1262     DeclRewriterBase<clang::CXXMethodDecl, clang::NamedDecl>;
   1263 using MethodRefRewriter =
   1264     DeclRewriterBase<clang::CXXMethodDecl, clang::DeclRefExpr>;
   1265 using MethodMemberRewriter =
   1266     DeclRewriterBase<clang::CXXMethodDecl, clang::MemberExpr>;
   1267 
   1268 using EnumConstantDeclRewriter =
   1269     DeclRewriterBase<clang::EnumConstantDecl, clang::NamedDecl>;
   1270 using EnumConstantDeclRefRewriter =
   1271     DeclRewriterBase<clang::EnumConstantDecl, clang::DeclRefExpr>;
   1272 
   1273 using UnresolvedLookupRewriter =
   1274     DeclRewriterBase<clang::NamedDecl, clang::UnresolvedLookupExpr>;
   1275 using UnresolvedMemberRewriter =
   1276     DeclRewriterBase<clang::NamedDecl, clang::UnresolvedMemberExpr>;
   1277 
   1278 using UsingDeclRewriter = DeclRewriterBase<clang::UsingDecl, clang::NamedDecl>;
   1279 
   1280 class GMockMemberRewriter
   1281     : public DeclRewriterBase<clang::CXXMethodDecl, clang::MemberExpr> {
   1282  public:
   1283   using Base = DeclRewriterBase<clang::CXXMethodDecl, clang::MemberExpr>;
   1284 
   1285   explicit GMockMemberRewriter(std::set<Replacement>* replacements)
   1286       : Base(replacements) {}
   1287 
   1288   std::unique_ptr<clang::PPCallbacks> CreatePreprocessorCallbacks() {
   1289     return llvm::make_unique<GMockMemberRewriter::PPCallbacks>(this);
   1290   }
   1291 
   1292   clang::SourceLocation GetTargetLoc(
   1293       const MatchFinder::MatchResult& result) override {
   1294     // Find location of the gmock_##MockedMethod identifier.
   1295     clang::SourceLocation target_loc = Base::GetTargetLoc(result);
   1296 
   1297     // Find location of EXPECT_CALL or ON_CALL macro invocation.
   1298     clang::SourceLocation macro_call_loc =
   1299         result.SourceManager->getExpansionLoc(target_loc);
   1300 
   1301     // Map |macro_call_loc| to argument location (location of the method name
   1302     // that needs renaming).
   1303     auto it = gmock_macro_call_to_2nd_arg.find(macro_call_loc);
   1304     if (it == gmock_macro_call_to_2nd_arg.end())
   1305       return clang::SourceLocation();
   1306     return it->second;
   1307   }
   1308 
   1309  private:
   1310   std::map<clang::SourceLocation, clang::SourceLocation>
   1311       gmock_macro_call_to_2nd_arg;
   1312 
   1313   // Called from PPCallbacks with the locations of EXPECT_CALL and ON_CALL macro
   1314   // invocation.  Example:
   1315   //   EXPECT_CALL(my_mock, myMethod(123, 456));
   1316   //   ^- expansion_loc     ^- actual_arg_loc
   1317   void RecordGMockMacroInvocation(clang::SourceLocation expansion_loc,
   1318                                   clang::SourceLocation second_arg_loc) {
   1319     gmock_macro_call_to_2nd_arg[expansion_loc] = second_arg_loc;
   1320   }
   1321 
   1322   class PPCallbacks : public clang::PPCallbacks {
   1323    public:
   1324     explicit PPCallbacks(GMockMemberRewriter* rewriter) : rewriter_(rewriter) {}
   1325     ~PPCallbacks() override {}
   1326     void MacroExpands(const clang::Token& name,
   1327                       const clang::MacroDefinition& def,
   1328                       clang::SourceRange range,
   1329                       const clang::MacroArgs* args) override {
   1330       clang::IdentifierInfo* id = name.getIdentifierInfo();
   1331       if (!id)
   1332         return;
   1333 
   1334       if (id->getName() != "EXPECT_CALL" && id->getName() != "ON_CALL")
   1335         return;
   1336 
   1337       if (def.getMacroInfo()->getNumParams() != 2)
   1338         return;
   1339 
   1340       // TODO(lukasza): Should check if def.getMacroInfo()->getDefinitionLoc()
   1341       // is in testing/gmock/include/gmock/gmock-spec-builders.h but I don't
   1342       // know how to get clang::SourceManager to call getFileName.
   1343 
   1344       rewriter_->RecordGMockMacroInvocation(
   1345           name.getLocation(), args->getUnexpArgument(1)->getLocation());
   1346     }
   1347 
   1348    private:
   1349     GMockMemberRewriter* rewriter_;
   1350   };
   1351 };
   1352 
   1353 clang::DeclarationName GetUnresolvedName(
   1354     const clang::UnresolvedMemberExpr& expr) {
   1355   return expr.getMemberName();
   1356 }
   1357 
   1358 clang::DeclarationName GetUnresolvedName(
   1359     const clang::DependentScopeDeclRefExpr& expr) {
   1360   return expr.getDeclName();
   1361 }
   1362 
   1363 clang::DeclarationName GetUnresolvedName(
   1364     const clang::CXXDependentScopeMemberExpr& expr) {
   1365   return expr.getMember();
   1366 }
   1367 
   1368 clang::DeclarationName GetUnresolvedName(
   1369     const clang::UnresolvedUsingValueDecl& decl) {
   1370   return decl.getDeclName();
   1371 }
   1372 
   1373 // Returns whether |expr_node| is used as a callee in the AST (i.e. if
   1374 // |expr_node| needs to resolve to a method or a function).
   1375 bool IsCallee(const clang::Expr& expr, clang::ASTContext& context) {
   1376   auto matcher = stmt(hasParent(callExpr(callee(equalsNode(&expr)))));
   1377   return IsMatching(matcher, expr, context);
   1378 }
   1379 
   1380 // Returns whether |decl| will be used as a callee in the AST (i.e. if the value
   1381 // brought by the using declaration will resolve to a method or a function).
   1382 bool IsCallee(const clang::UnresolvedUsingValueDecl& decl,
   1383               clang::ASTContext& /* context */) {
   1384   // Caller (i.e. GuessNameForUnresolvedDependentNode) should have already
   1385   // filtered out fields before calling |IsCallee|.
   1386   clang::IdentifierInfo* info = GetUnresolvedName(decl).getAsIdentifierInfo();
   1387   assert(info);
   1388   bool name_looks_like_a_field = info->getName().startswith(kBlinkFieldPrefix);
   1389   assert(!name_looks_like_a_field);
   1390 
   1391   // Looking just at clang::UnresolvedUsingValueDecl, we cannot tell whether it
   1392   // refers to something callable or not.  Since fields should have been already
   1393   // filtered out before calling IsCallee (see the assert above), let's assume
   1394   // that |using Base::foo| refers to a method.
   1395   return true;
   1396 }
   1397 
   1398 template <typename TargetNode>
   1399 class UnresolvedRewriterBase : public RewriterBase<TargetNode> {
   1400  public:
   1401   using Base = RewriterBase<TargetNode>;
   1402 
   1403   explicit UnresolvedRewriterBase(std::set<Replacement>* replacements)
   1404       : RewriterBase<TargetNode>(replacements, RenameCategory::kUnresolved) {}
   1405 
   1406   void run(const MatchFinder::MatchResult& result) override {
   1407     const TargetNode& node = Base::GetTargetNode(result);
   1408 
   1409     clang::DeclarationName decl_name = GetUnresolvedName(node);
   1410     switch (decl_name.getNameKind()) {
   1411       // Do not rewrite this:
   1412       //   return operator T*();
   1413       // into this:
   1414       //   return Operator type - parameter - 0 - 0 * T * ();
   1415       case clang::DeclarationName::NameKind::CXXConversionFunctionName:
   1416       case clang::DeclarationName::NameKind::CXXOperatorName:
   1417       case clang::DeclarationName::NameKind::CXXLiteralOperatorName:
   1418         return;
   1419       default:
   1420         break;
   1421     }
   1422 
   1423     // Make sure there is an old name + extract the old name.
   1424     clang::IdentifierInfo* info = GetUnresolvedName(node).getAsIdentifierInfo();
   1425     if (!info)
   1426       return;
   1427     llvm::StringRef old_name = info->getName();
   1428 
   1429     // Try to guess a new name.
   1430     std::string new_name;
   1431     if (GuessNameForUnresolvedDependentNode(node, *result.Context, old_name,
   1432                                             new_name))
   1433       Base::AddReplacement(result, old_name, std::move(new_name));
   1434   }
   1435 
   1436  private:
   1437   // This method calculates a new name for nodes that depend on template
   1438   // parameters (http://en.cppreference.com/w/cpp/language/dependent_name).  The
   1439   // renaming is based on crude heuristics, because such nodes are not bound to
   1440   // a specific decl until template instantiation - at the point of rename, one
   1441   // cannot tell whether the node will eventually resolve to a field / method /
   1442   // constant / etc.
   1443   //
   1444   // The method returns false if no renaming should be done.
   1445   // Otherwise the method returns true and sets |new_name|.
   1446   bool GuessNameForUnresolvedDependentNode(const TargetNode& node,
   1447                                            clang::ASTContext& context,
   1448                                            llvm::StringRef old_name,
   1449                                            std::string& new_name) {
   1450     // |m_fieldName| -> |field_name_|.
   1451     if (old_name.startswith(kBlinkFieldPrefix)) {
   1452       std::string field_name = old_name.substr(strlen(kBlinkFieldPrefix));
   1453       if (field_name.find('_') == std::string::npos) {
   1454         new_name = CamelCaseToUnderscoreCase(field_name) + "_";
   1455         return true;
   1456       }
   1457     }
   1458 
   1459     // |T::myMethod(...)| -> |T::MyMethod(...)|.
   1460     if ((old_name.find('_') == std::string::npos) && IsCallee(node, context) &&
   1461         !IsBlacklistedMethodName(old_name)) {
   1462       new_name = old_name;
   1463       new_name[0] = clang::toUppercase(old_name[0]);
   1464       if (ShouldPrefixFunctionName(old_name))
   1465         new_name = "Get" + new_name;
   1466       return true;
   1467     }
   1468 
   1469     // In the future we can consider more heuristics:
   1470     // - "s_" and "g_" prefixes
   1471     // - "ALL_CAPS"
   1472     // - |T::myStaticField| -> |T::kMyStaticField|
   1473     //   (but have to be careful not to rename |value| in WTF/TypeTraits.h?)
   1474     return false;
   1475   }
   1476 };
   1477 
   1478 using UnresolvedDependentMemberRewriter =
   1479     UnresolvedRewriterBase<clang::UnresolvedMemberExpr>;
   1480 
   1481 using UnresolvedUsingValueDeclRewriter =
   1482     UnresolvedRewriterBase<clang::UnresolvedUsingValueDecl>;
   1483 
   1484 using DependentScopeDeclRefExprRewriter =
   1485     UnresolvedRewriterBase<clang::DependentScopeDeclRefExpr>;
   1486 
   1487 using CXXDependentScopeMemberExprRewriter =
   1488     UnresolvedRewriterBase<clang::CXXDependentScopeMemberExpr>;
   1489 
   1490 class SourceFileCallbacks : public clang::tooling::SourceFileCallbacks {
   1491  public:
   1492   explicit SourceFileCallbacks(GMockMemberRewriter* gmock_member_rewriter)
   1493       : gmock_member_rewriter_(gmock_member_rewriter) {
   1494     assert(gmock_member_rewriter);
   1495   }
   1496 
   1497   ~SourceFileCallbacks() override {}
   1498 
   1499   // clang::tooling::SourceFileCallbacks override:
   1500   bool handleBeginSource(clang::CompilerInstance& compiler) override {
   1501     compiler.getPreprocessor().addPPCallbacks(
   1502         gmock_member_rewriter_->CreatePreprocessorCallbacks());
   1503     return true;
   1504   }
   1505 
   1506  private:
   1507   GMockMemberRewriter* gmock_member_rewriter_;
   1508 };
   1509 
   1510 }  // namespace
   1511 
   1512 static llvm::cl::extrahelp common_help(CommonOptionsParser::HelpMessage);
   1513 
   1514 int main(int argc, const char* argv[]) {
   1515   // TODO(dcheng): Clang tooling should do this itself.
   1516   // http://llvm.org/bugs/show_bug.cgi?id=21627
   1517   llvm::InitializeNativeTarget();
   1518   llvm::InitializeNativeTargetAsmParser();
   1519   llvm::cl::OptionCategory category(
   1520       "rewrite_to_chrome_style: convert Blink style to Chrome style.");
   1521   llvm::cl::opt<std::string> blocklisted_methods_file(
   1522       kMethodBlocklistParamName, llvm::cl::value_desc("filepath"),
   1523       llvm::cl::desc("file listing methods to be blocked (not renamed)"));
   1524   CommonOptionsParser options(argc, argv, category);
   1525   MethodBlocklist method_blocklist(blocklisted_methods_file);
   1526   clang::tooling::ClangTool tool(options.getCompilations(),
   1527                                  options.getSourcePathList());
   1528 
   1529   MatchFinder match_finder;
   1530   std::set<Replacement> replacements;
   1531 
   1532   // Blink namespace matchers ========
   1533   auto blink_namespace_decl =
   1534       namespaceDecl(anyOf(hasName("blink"), hasName("WTF")),
   1535                     hasParent(translationUnitDecl()));
   1536   auto protocol_namespace_decl =
   1537       namespaceDecl(hasName("protocol"),
   1538                     hasParent(namespaceDecl(hasName("blink"),
   1539                                             hasParent(translationUnitDecl()))));
   1540 
   1541   // Given top-level compilation unit:
   1542   //   namespace WTF {
   1543   //     void foo() {}
   1544   //   }
   1545   // matches |foo|.
   1546   auto decl_under_blink_namespace =
   1547       decl(hasAncestor(blink_namespace_decl),
   1548            unless(hasAncestor(protocol_namespace_decl)));
   1549 
   1550   // Given top-level compilation unit:
   1551   //   void WTF::function() {}
   1552   //   void WTF::Class::method() {}
   1553   // matches |WTF::function| and |WTF::Class::method| decls.
   1554   auto decl_has_qualifier_to_blink_namespace =
   1555       declaratorDecl(has(nestedNameSpecifier(
   1556           hasTopLevelPrefix(specifiesNamespace(blink_namespace_decl)))));
   1557 
   1558   auto in_blink_namespace = decl(
   1559       anyOf(decl_under_blink_namespace, decl_has_qualifier_to_blink_namespace,
   1560             hasAncestor(decl_has_qualifier_to_blink_namespace)),
   1561       unless(hasCanonicalDecl(isDeclInGeneratedFile())));
   1562 
   1563   // Field, variable, and enum declarations ========
   1564   // Given
   1565   //   int x;
   1566   //   struct S {
   1567   //     int y;
   1568   //     enum { VALUE };
   1569   //   };
   1570   // matches |x|, |y|, and |VALUE|.
   1571   auto field_decl_matcher = id("decl", fieldDecl(in_blink_namespace));
   1572   auto is_type_trait_value =
   1573       varDecl(hasName("value"), hasStaticStorageDuration(), isPublic(),
   1574               hasType(isConstQualified()),
   1575               hasType(type(anyOf(builtinType(), enumType()))),
   1576               unless(hasAncestor(recordDecl(
   1577                   has(cxxMethodDecl(isUserProvided(), isInstanceMethod()))))));
   1578   auto var_decl_matcher =
   1579       id("decl", varDecl(in_blink_namespace, unless(is_type_trait_value)));
   1580   // For known trait names, rename every instance anywhere in the codebase.
   1581   auto type_trait_decl_matcher = id("decl", varDecl(isKnownTraitName()));
   1582   auto enum_member_decl_matcher =
   1583       id("decl", enumConstantDecl(in_blink_namespace));
   1584 
   1585   FieldDeclRewriter field_decl_rewriter(&replacements);
   1586   match_finder.addMatcher(field_decl_matcher, &field_decl_rewriter);
   1587 
   1588   VarDeclRewriter var_decl_rewriter(&replacements);
   1589   match_finder.addMatcher(var_decl_matcher, &var_decl_rewriter);
   1590   match_finder.addMatcher(type_trait_decl_matcher, &var_decl_rewriter);
   1591 
   1592   EnumConstantDeclRewriter enum_member_decl_rewriter(&replacements);
   1593   match_finder.addMatcher(enum_member_decl_matcher, &enum_member_decl_rewriter);
   1594 
   1595   // Field, variable, and enum references ========
   1596   // Given
   1597   //   bool x = true;
   1598   //   if (x) {
   1599   //     ...
   1600   //   }
   1601   // matches |x| in if (x).
   1602   auto member_matcher = id(
   1603       "expr",
   1604       memberExpr(
   1605           member(field_decl_matcher),
   1606           // Needed to avoid matching member references in functions (which will
   1607           // be an ancestor of the member reference) synthesized by the
   1608           // compiler, such as a synthesized copy constructor.
   1609           // This skips explicitly defaulted functions as well, but that's OK:
   1610           // there's nothing interesting to rewrite in those either.
   1611           unless(hasAncestor(functionDecl(isDefaulted())))));
   1612   auto decl_ref_matcher = id("expr", declRefExpr(to(var_decl_matcher)));
   1613   auto type_trait_ref_matcher =
   1614       id("expr", declRefExpr(to(type_trait_decl_matcher)));
   1615   auto enum_member_ref_matcher =
   1616       id("expr", declRefExpr(to(enum_member_decl_matcher)));
   1617 
   1618   MemberRewriter member_rewriter(&replacements);
   1619   match_finder.addMatcher(member_matcher, &member_rewriter);
   1620 
   1621   DeclRefRewriter decl_ref_rewriter(&replacements);
   1622   match_finder.addMatcher(decl_ref_matcher, &decl_ref_rewriter);
   1623   match_finder.addMatcher(type_trait_ref_matcher, &decl_ref_rewriter);
   1624 
   1625   EnumConstantDeclRefRewriter enum_member_ref_rewriter(&replacements);
   1626   match_finder.addMatcher(enum_member_ref_matcher, &enum_member_ref_rewriter);
   1627 
   1628   // Member references in a non-member context ========
   1629   // Given
   1630   //   struct S {
   1631   //     typedef int U::*UnspecifiedBoolType;
   1632   //     operator UnspecifiedBoolType() { return s_ ? &U::s_ : 0; }
   1633   //     int s_;
   1634   //   };
   1635   // matches |&U::s_| but not |s_|.
   1636   auto member_ref_matcher = id("expr", declRefExpr(to(field_decl_matcher)));
   1637 
   1638   FieldDeclRefRewriter member_ref_rewriter(&replacements);
   1639   match_finder.addMatcher(member_ref_matcher, &member_ref_rewriter);
   1640 
   1641   // Non-method function declarations ========
   1642   // Given
   1643   //   void f();
   1644   //   struct S {
   1645   //     void g();
   1646   //   };
   1647   // matches |f| but not |g|.
   1648   auto function_decl_matcher = id(
   1649       "decl",
   1650       functionDecl(
   1651           unless(anyOf(
   1652               // Methods are covered by the method matchers.
   1653               cxxMethodDecl(),
   1654               // Out-of-line overloaded operators have special names and should
   1655               // never be renamed.
   1656               isOverloadedOperator(),
   1657               // Must be checked after filtering out overloaded operators to
   1658               // prevent asserts about the identifier not being a simple name.
   1659               isBlacklistedFunction(),
   1660               // Functions that look like blocked static methods.
   1661               isBlocklistedMethod(method_blocklist))),
   1662           in_blink_namespace));
   1663   FunctionDeclRewriter function_decl_rewriter(&replacements);
   1664   match_finder.addMatcher(function_decl_matcher, &function_decl_rewriter);
   1665 
   1666   // Non-method function references ========
   1667   // Given
   1668   //   f();
   1669   //   void (*p)() = &f;
   1670   // matches |f()| and |&f|.
   1671   auto function_ref_matcher = id(
   1672       "expr", declRefExpr(to(function_decl_matcher),
   1673                           // Ignore template substitutions.
   1674                           unless(hasAncestor(substNonTypeTemplateParmExpr()))));
   1675   FunctionRefRewriter function_ref_rewriter(&replacements);
   1676   match_finder.addMatcher(function_ref_matcher, &function_ref_rewriter);
   1677 
   1678   // Method declarations ========
   1679   // Given
   1680   //   struct S {
   1681   //     void g();
   1682   //   };
   1683   // matches |g|.
   1684   // For a method to be considered for rewrite, it must not override something
   1685   // that we're not rewriting. Any methods that we would not normally consider
   1686   // but that override something we are rewriting should also be rewritten. So
   1687   // we use includeAllOverriddenMethods() to check these rules not just for the
   1688   // method being matched but for the methods it overrides also.
   1689   auto is_blink_method = includeAllOverriddenMethods(
   1690       allOf(in_blink_namespace,
   1691             unless(anyOf(isBlacklistedMethod(),
   1692                          isBlocklistedMethod(method_blocklist)))));
   1693   auto method_decl_matcher = id(
   1694       "decl",
   1695       cxxMethodDecl(
   1696           unless(anyOf(
   1697               // Overloaded operators have special names and should never be
   1698               // renamed.
   1699               isOverloadedOperator(),
   1700               // Similarly, constructors, destructors, and conversion
   1701               // functions should not be considered for renaming.
   1702               cxxConstructorDecl(), cxxDestructorDecl(), cxxConversionDecl())),
   1703           // Check this last after excluding things, to avoid
   1704           // asserts about overriding non-blink and blink for the
   1705           // same method.
   1706           is_blink_method));
   1707   MethodDeclRewriter method_decl_rewriter(&replacements);
   1708   match_finder.addMatcher(method_decl_matcher, &method_decl_rewriter);
   1709 
   1710   // Method references in a non-member context ========
   1711   // Given
   1712   //   S s;
   1713   //   s.g();
   1714   //   void (S::*p)() = &S::g;
   1715   // matches |&S::g| but not |s.g|.
   1716   auto method_ref_matcher = id(
   1717       "expr", declRefExpr(to(method_decl_matcher),
   1718                           // Ignore template substitutions.
   1719                           unless(hasAncestor(substNonTypeTemplateParmExpr()))));
   1720 
   1721   MethodRefRewriter method_ref_rewriter(&replacements);
   1722   match_finder.addMatcher(method_ref_matcher, &method_ref_rewriter);
   1723 
   1724   // Method references in a member context ========
   1725   // Given
   1726   //   S s;
   1727   //   s.g();
   1728   //   void (S::*p)() = &S::g;
   1729   // matches |s.g| but not |&S::g|.
   1730   auto method_member_matcher =
   1731       id("expr", memberExpr(member(method_decl_matcher)));
   1732 
   1733   MethodMemberRewriter method_member_rewriter(&replacements);
   1734   match_finder.addMatcher(method_member_matcher, &method_member_rewriter);
   1735 
   1736   // Initializers ========
   1737   // Given
   1738   //   struct S {
   1739   //     int x;
   1740   //     S() : x(2) {}
   1741   //   };
   1742   // matches each initializer in the constructor for S.
   1743   auto constructor_initializer_matcher =
   1744       cxxConstructorDecl(forEachConstructorInitializer(id(
   1745           "initializer",
   1746           cxxCtorInitializer(forAnyField(field_decl_matcher), isWritten()))));
   1747 
   1748   ConstructorInitializerRewriter constructor_initializer_rewriter(
   1749       &replacements);
   1750   match_finder.addMatcher(constructor_initializer_matcher,
   1751                           &constructor_initializer_rewriter);
   1752 
   1753   // Unresolved lookup expressions ========
   1754   // Given
   1755   //   template<typename T> void F(T) { }
   1756   //   template<void G(T)> H(T) { }
   1757   //   H<F<int>>(...);
   1758   // matches |F| in |H<F<int>>|.
   1759   //
   1760   // UnresolvedLookupExprs are similar to DeclRefExprs that reference a
   1761   // FunctionDecl, but are used when a candidate FunctionDecl can't be selected.
   1762   // This commonly happens inside uninstantiated template definitions for one of
   1763   // two reasons:
   1764   //
   1765   // 1. If the candidate declaration is a dependent FunctionTemplateDecl, the
   1766   //    actual overload can't be selected until template instantiation time.
   1767   // 2. Alternatively, there might be multiple declarations in the candidate set
   1768   //    if the candidate function has overloads. If any of the function
   1769   //    arguments has a dependent type, then the actual overload can't be
   1770   //    selected until instantiation time either.
   1771   //
   1772   // Another instance where UnresolvedLookupExprs can appear is in a template
   1773   // argument list, like the provided example.
   1774   auto function_template_decl_matcher =
   1775       id("decl", functionTemplateDecl(templatedDecl(function_decl_matcher)));
   1776   auto method_template_decl_matcher =
   1777       id("decl", functionTemplateDecl(templatedDecl(method_decl_matcher)));
   1778   auto unresolved_lookup_matcher = expr(id(
   1779       "expr",
   1780       unresolvedLookupExpr(
   1781           // In order to automatically rename an unresolved lookup, the lookup
   1782           // candidates must either all be Blink functions/function templates or
   1783           // all be Blink methods/method templates. Otherwise, we might end up
   1784           // in a situation where the naming could change depending on the
   1785           // selected candidate.
   1786           anyOf(allOverloadsMatch(anyOf(function_decl_matcher,
   1787                                         function_template_decl_matcher)),
   1788                 // Note: this matches references to methods in a non-member
   1789                 // context, e.g. Template<&Class::Method>. This and the
   1790                 // UnresolvedMemberExpr matcher below are analogous to how the
   1791                 // rewriter has both a MemberRefRewriter matcher to rewrite
   1792                 // &T::method and a MethodMemberRewriter matcher to rewriter
   1793                 // t.method().
   1794                 allOverloadsMatch(anyOf(method_decl_matcher,
   1795                                         method_template_decl_matcher))))));
   1796   UnresolvedLookupRewriter unresolved_lookup_rewriter(&replacements);
   1797   match_finder.addMatcher(unresolved_lookup_matcher,
   1798                           &unresolved_lookup_rewriter);
   1799 
   1800   // Unresolved member expressions (for non-dependent fields / methods) ========
   1801   // Similar to unresolved lookup expressions, but for methods in a member
   1802   // context, e.g. var_with_templated_type.Method().
   1803   auto unresolved_member_matcher = expr(id(
   1804       "expr",
   1805       unresolvedMemberExpr(
   1806           // Similar to UnresolvedLookupExprs, all the candidate methods must be
   1807           // Blink methods/method templates.
   1808           allOverloadsMatch(
   1809               anyOf(method_decl_matcher, method_template_decl_matcher)))));
   1810   UnresolvedMemberRewriter unresolved_member_rewriter(&replacements);
   1811   match_finder.addMatcher(unresolved_member_matcher,
   1812                           &unresolved_member_rewriter);
   1813 
   1814   // Unresolved using value decls ========
   1815   // Example:
   1816   //  template <typename T>
   1817   //  class BaseClass {
   1818   //   public:
   1819   //    unsigned long m_size;
   1820   //  };
   1821   //  template <typename T>
   1822   //  class DerivedClass : protected BaseClass<T> {
   1823   //   private:
   1824   //    using Base = BaseClass<T>;
   1825   //    using Base::m_size;  // <- |m_size| here is matched by
   1826   //    void method() {      //    |unresolved_using_value_decl_matcher|.
   1827   //      m_size = 123;  // <- |m_size| here is matched by
   1828   //    }                //    |unresolved_dependent_using_matcher|.
   1829   //  };
   1830   auto unresolved_dependent_using_matcher =
   1831       expr(id("expr", unresolvedMemberExpr(allOverloadsMatch(allOf(
   1832                           in_blink_namespace, unresolvedUsingValueDecl())))));
   1833   UnresolvedDependentMemberRewriter unresolved_dependent_member_rewriter(
   1834       &replacements);
   1835   match_finder.addMatcher(unresolved_dependent_using_matcher,
   1836                           &unresolved_dependent_member_rewriter);
   1837   auto unresolved_using_value_decl_matcher =
   1838       decl(id("decl", unresolvedUsingValueDecl(in_blink_namespace)));
   1839   UnresolvedUsingValueDeclRewriter unresolved_using_value_decl_rewriter(
   1840       &replacements);
   1841   match_finder.addMatcher(unresolved_using_value_decl_matcher,
   1842                           &unresolved_using_value_decl_rewriter);
   1843 
   1844   // Using declarations ========
   1845   // Given
   1846   //   using blink::X;
   1847   // matches |using blink::X|.
   1848   auto using_decl_matcher = id(
   1849       "decl", usingDecl(hasAnyUsingShadowDecl(hasTargetDecl(anyOf(
   1850                   var_decl_matcher, field_decl_matcher, function_decl_matcher,
   1851                   method_decl_matcher, function_template_decl_matcher,
   1852                   method_template_decl_matcher, enum_member_decl_matcher)))));
   1853   UsingDeclRewriter using_decl_rewriter(&replacements);
   1854   match_finder.addMatcher(using_decl_matcher, &using_decl_rewriter);
   1855 
   1856   // Matches any QualType that refers to a blink type:
   1857   // - const blink::Foo&
   1858   // - blink::Foo*
   1859   // - blink::Foo<T>
   1860   auto blink_qual_type_base_matcher = hasBaseType(hasUnqualifiedDesugaredType(
   1861       anyOf(enumType(hasDeclaration(in_blink_namespace)),
   1862             injectedClassNameType(hasDeclaration(in_blink_namespace)),
   1863             recordType(hasDeclaration(in_blink_namespace)),
   1864             templateSpecializationType(hasDeclaration(in_blink_namespace)),
   1865             templateTypeParmType(hasDeclaration(in_blink_namespace)))));
   1866   auto blink_qual_type_matcher = qualType(anyOf(
   1867       blink_qual_type_base_matcher, pointsTo(blink_qual_type_base_matcher),
   1868       references(blink_qual_type_base_matcher)));
   1869 
   1870   // Template-dependent decl lookup ========
   1871   // Given
   1872   //   template <typename T> void f() { T::foo(); }
   1873   // matches |T::foo|.
   1874   auto dependent_scope_decl_ref_expr_matcher =
   1875       expr(id("expr", dependentScopeDeclRefExpr(has(nestedNameSpecifier(
   1876                           specifiesType(blink_qual_type_matcher))))));
   1877   DependentScopeDeclRefExprRewriter dependent_scope_decl_ref_expr_rewriter(
   1878       &replacements);
   1879   match_finder.addMatcher(dependent_scope_decl_ref_expr_matcher,
   1880                           &dependent_scope_decl_ref_expr_rewriter);
   1881 
   1882   // Template-dependent member lookup ========
   1883   // Given
   1884   //   template <typename T>
   1885   //   class Foo {
   1886   //     void f() { T::foo(); }
   1887   //     void g(T x) { x.bar(); }
   1888   //   };
   1889   // matches |T::foo| and |x.bar|.
   1890   auto cxx_dependent_scope_member_expr_matcher =
   1891       expr(id("expr", cxxDependentScopeMemberExpr(
   1892                           hasMemberFromType(blink_qual_type_matcher))));
   1893   CXXDependentScopeMemberExprRewriter cxx_dependent_scope_member_expr_rewriter(
   1894       &replacements);
   1895   match_finder.addMatcher(cxx_dependent_scope_member_expr_matcher,
   1896                           &cxx_dependent_scope_member_expr_rewriter);
   1897 
   1898   // GMock calls lookup ========
   1899   // Given
   1900   //   EXPECT_CALL(obj, myMethod(...))
   1901   // or
   1902   //   ON_CALL(obj, myMethod(...))
   1903   // will match obj.gmock_myMethod(...) call generated by the macros
   1904   // (but only if it mocks a Blink method).
   1905   auto gmock_member_matcher =
   1906       id("expr", memberExpr(hasDeclaration(
   1907                      decl(cxxMethodDecl(mocksMethod(method_decl_matcher))))));
   1908   GMockMemberRewriter gmock_member_rewriter(&replacements);
   1909   match_finder.addMatcher(gmock_member_matcher, &gmock_member_rewriter);
   1910 
   1911   // Prepare and run the tool.
   1912   SourceFileCallbacks source_file_callbacks(&gmock_member_rewriter);
   1913   std::unique_ptr<clang::tooling::FrontendActionFactory> factory =
   1914       clang::tooling::newFrontendActionFactory(&match_finder,
   1915                                                &source_file_callbacks);
   1916   int result = tool.run(factory.get());
   1917   if (result != 0)
   1918     return result;
   1919 
   1920   // Supplemental data for the Blink rename rebase helper.
   1921   std::vector<const EditTracker*> all_edit_trackers{
   1922       field_decl_rewriter.edit_tracker(),
   1923       var_decl_rewriter.edit_tracker(),
   1924       enum_member_decl_rewriter.edit_tracker(),
   1925       member_rewriter.edit_tracker(),
   1926       decl_ref_rewriter.edit_tracker(),
   1927       enum_member_ref_rewriter.edit_tracker(),
   1928       member_ref_rewriter.edit_tracker(),
   1929       function_decl_rewriter.edit_tracker(),
   1930       function_ref_rewriter.edit_tracker(),
   1931       method_decl_rewriter.edit_tracker(),
   1932       method_ref_rewriter.edit_tracker(),
   1933       method_member_rewriter.edit_tracker(),
   1934       constructor_initializer_rewriter.edit_tracker(),
   1935       unresolved_lookup_rewriter.edit_tracker(),
   1936       unresolved_member_rewriter.edit_tracker(),
   1937       unresolved_dependent_member_rewriter.edit_tracker(),
   1938       unresolved_using_value_decl_rewriter.edit_tracker(),
   1939       using_decl_rewriter.edit_tracker(),
   1940       dependent_scope_decl_ref_expr_rewriter.edit_tracker(),
   1941       cxx_dependent_scope_member_expr_rewriter.edit_tracker(),
   1942       gmock_member_rewriter.edit_tracker(),
   1943   };
   1944   llvm::outs() << "==== BEGIN TRACKED EDITS ====\n";
   1945   for (const EditTracker* edit_tracker : all_edit_trackers)
   1946     edit_tracker->SerializeTo(llvm::outs());
   1947   llvm::outs() << "==== END TRACKED EDITS ====\n";
   1948 
   1949   // Serialization format is documented in tools/clang/scripts/run_tool.py
   1950   llvm::outs() << "==== BEGIN EDITS ====\n";
   1951   for (const auto& r : replacements) {
   1952     std::string replacement_text = r.getReplacementText().str();
   1953     std::replace(replacement_text.begin(), replacement_text.end(), '\n', '\0');
   1954     llvm::outs() << "r:::" << r.getFilePath() << ":::" << r.getOffset()
   1955                  << ":::" << r.getLength() << ":::" << replacement_text << "\n";
   1956   }
   1957   llvm::outs() << "==== END EDITS ====\n";
   1958 
   1959   return 0;
   1960 }
   1961