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 <fstream>
     18 #include <memory>
     19 #include <string>
     20 #include <unordered_map>
     21 
     22 #include "clang/AST/ASTContext.h"
     23 #include "clang/ASTMatchers/ASTMatchFinder.h"
     24 #include "clang/ASTMatchers/ASTMatchers.h"
     25 #include "clang/ASTMatchers/ASTMatchersMacros.h"
     26 #include "clang/Basic/CharInfo.h"
     27 #include "clang/Basic/SourceManager.h"
     28 #include "clang/Frontend/FrontendActions.h"
     29 #include "clang/Lex/Lexer.h"
     30 #include "clang/Tooling/CommonOptionsParser.h"
     31 #include "clang/Tooling/Refactoring.h"
     32 #include "clang/Tooling/Tooling.h"
     33 #include "llvm/Support/CommandLine.h"
     34 #include "llvm/Support/TargetSelect.h"
     35 
     36 #if defined(_WIN32)
     37 #include <windows.h>
     38 #else
     39 #include <sys/file.h>
     40 #include <unistd.h>
     41 #endif
     42 
     43 using namespace clang::ast_matchers;
     44 using clang::tooling::CommonOptionsParser;
     45 using clang::tooling::Replacement;
     46 using llvm::StringRef;
     47 
     48 namespace {
     49 
     50 const char kBlinkFieldPrefix[] = "m_";
     51 const char kBlinkStaticMemberPrefix[] = "s_";
     52 const char kGeneratedFileRegex[] = "^gen/|/gen/";
     53 
     54 const clang::ast_matchers::internal::
     55     VariadicDynCastAllOfMatcher<clang::Expr, clang::UnresolvedMemberExpr>
     56         unresolvedMemberExpr;
     57 
     58 AST_MATCHER(clang::FunctionDecl, isOverloadedOperator) {
     59   return Node.isOverloadedOperator();
     60 }
     61 
     62 AST_MATCHER(clang::CXXMethodDecl, isInstanceMethod) {
     63   return Node.isInstance();
     64 }
     65 
     66 AST_MATCHER_P(clang::FunctionTemplateDecl,
     67               templatedDecl,
     68               clang::ast_matchers::internal::Matcher<clang::FunctionDecl>,
     69               InnerMatcher) {
     70   return InnerMatcher.matches(*Node.getTemplatedDecl(), Finder, Builder);
     71 }
     72 
     73 // If |InnerMatcher| matches |top|, then the returned matcher will match:
     74 // - |top::function|
     75 // - |top::Class::method|
     76 // - |top::internal::Class::method|
     77 AST_MATCHER_P(
     78     clang::NestedNameSpecifier,
     79     hasTopLevelPrefix,
     80     clang::ast_matchers::internal::Matcher<clang::NestedNameSpecifier>,
     81     InnerMatcher) {
     82   const clang::NestedNameSpecifier* NodeToMatch = &Node;
     83   while (NodeToMatch->getPrefix())
     84     NodeToMatch = NodeToMatch->getPrefix();
     85   return InnerMatcher.matches(*NodeToMatch, Finder, Builder);
     86 }
     87 
     88 // This will narrow CXXCtorInitializers down for both FieldDecls and
     89 // IndirectFieldDecls (ie. anonymous unions and such). In both cases
     90 // getAnyMember() will return a FieldDecl which we can match against.
     91 AST_MATCHER_P(clang::CXXCtorInitializer,
     92               forAnyField,
     93               clang::ast_matchers::internal::Matcher<clang::FieldDecl>,
     94               InnerMatcher) {
     95   const clang::FieldDecl* NodeAsDecl = Node.getAnyMember();
     96   return (NodeAsDecl != nullptr &&
     97           InnerMatcher.matches(*NodeAsDecl, Finder, Builder));
     98 }
     99 
    100 // Matches if all the overloads in the lookup set match the provided matcher.
    101 AST_MATCHER_P(clang::OverloadExpr,
    102               allOverloadsMatch,
    103               clang::ast_matchers::internal::Matcher<clang::NamedDecl>,
    104               InnerMatcher) {
    105   if (Node.getNumDecls() == 0)
    106     return false;
    107 
    108   for (clang::NamedDecl* decl : Node.decls()) {
    109     if (!InnerMatcher.matches(*decl, Finder, Builder))
    110       return false;
    111   }
    112   return true;
    113 }
    114 
    115 template <typename T>
    116 bool MatchAllOverriddenMethods(
    117     const clang::CXXMethodDecl& decl,
    118     T&& inner_matcher,
    119     clang::ast_matchers::internal::ASTMatchFinder* finder,
    120     clang::ast_matchers::internal::BoundNodesTreeBuilder* builder) {
    121   bool override_matches = false;
    122   bool override_not_matches = false;
    123 
    124   for (auto it = decl.begin_overridden_methods();
    125        it != decl.end_overridden_methods(); ++it) {
    126     if (MatchAllOverriddenMethods(**it, inner_matcher, finder, builder))
    127       override_matches = true;
    128     else
    129       override_not_matches = true;
    130   }
    131 
    132   // If this fires we have a class overriding a method that matches, and a
    133   // method that does not match the inner matcher. In that case we will match
    134   // one ancestor method but not the other. If we rename one of the and not the
    135   // other it will break what this class overrides, disconnecting it from the
    136   // one we did not rename which creates a behaviour change. So assert and
    137   // demand the user to fix the code first (or add the method to our
    138   // blacklist T_T).
    139   if (override_matches || override_not_matches)
    140     assert(override_matches != override_not_matches);
    141 
    142   // If the method overrides something that doesn't match, so the method itself
    143   // doesn't match.
    144   if (override_not_matches)
    145     return false;
    146   // If the method overrides something that matches, so the method ifself
    147   // matches.
    148   if (override_matches)
    149     return true;
    150 
    151   return inner_matcher.matches(decl, finder, builder);
    152 }
    153 
    154 AST_MATCHER_P(clang::CXXMethodDecl,
    155               includeAllOverriddenMethods,
    156               clang::ast_matchers::internal::Matcher<clang::CXXMethodDecl>,
    157               InnerMatcher) {
    158   return MatchAllOverriddenMethods(Node, InnerMatcher, Finder, Builder);
    159 }
    160 
    161 bool IsMethodOverrideOf(const clang::CXXMethodDecl& decl,
    162                         const char* class_name) {
    163   if (decl.getParent()->getQualifiedNameAsString() == class_name)
    164     return true;
    165   for (auto it = decl.begin_overridden_methods();
    166        it != decl.end_overridden_methods(); ++it) {
    167     if (IsMethodOverrideOf(**it, class_name))
    168       return true;
    169   }
    170   return false;
    171 }
    172 
    173 bool IsBlacklistedFunction(const clang::FunctionDecl& decl) {
    174   // swap() functions should match the signature of std::swap for ADL tricks.
    175   return decl.getName() == "swap";
    176 }
    177 
    178 bool IsBlacklistedMethod(const clang::CXXMethodDecl& decl) {
    179   if (decl.isStatic())
    180     return false;
    181 
    182   clang::StringRef name = decl.getName();
    183 
    184   // These methods should never be renamed.
    185   static const char* kBlacklistMethods[] = {"trace", "traceImpl", "lock",
    186                                             "unlock", "try_lock"};
    187   for (const auto& b : kBlacklistMethods) {
    188     if (name == b)
    189       return true;
    190   }
    191 
    192   // Iterator methods shouldn't be renamed to work with stl and range-for
    193   // loops.
    194   std::string ret_type = decl.getReturnType().getAsString();
    195   if (ret_type.find("iterator") != std::string::npos ||
    196       ret_type.find("Iterator") != std::string::npos) {
    197     static const char* kIteratorBlacklist[] = {"begin", "end", "rbegin",
    198                                                "rend"};
    199     for (const auto& b : kIteratorBlacklist) {
    200       if (name == b)
    201         return true;
    202     }
    203   }
    204 
    205   // Subclasses of InspectorAgent will subclass "disable()" from both blink and
    206   // from gen/, which is problematic, but DevTools folks don't want to rename
    207   // it or split this up. So don't rename it at all.
    208   if (name.equals("disable") &&
    209       IsMethodOverrideOf(decl, "blink::InspectorAgent"))
    210     return true;
    211 
    212   return false;
    213 }
    214 
    215 AST_MATCHER(clang::FunctionDecl, isBlacklistedFunction) {
    216   return IsBlacklistedFunction(Node);
    217 }
    218 
    219 AST_MATCHER(clang::CXXMethodDecl, isBlacklistedMethod) {
    220   return IsBlacklistedMethod(Node);
    221 }
    222 
    223 // Helper to convert from a camelCaseName to camel_case_name. It uses some
    224 // heuristics to try to handle acronyms in camel case names correctly.
    225 std::string CamelCaseToUnderscoreCase(StringRef input) {
    226   std::string output;
    227   bool needs_underscore = false;
    228   bool was_lowercase = false;
    229   bool was_uppercase = false;
    230   bool first_char = true;
    231   // Iterate in reverse to minimize the amount of backtracking.
    232   for (const unsigned char* i = input.bytes_end() - 1; i >= input.bytes_begin();
    233        --i) {
    234     char c = *i;
    235     bool is_lowercase = clang::isLowercase(c);
    236     bool is_uppercase = clang::isUppercase(c);
    237     c = clang::toLowercase(c);
    238     // Transitioning from upper to lower case requires an underscore. This is
    239     // needed to handle names with acronyms, e.g. handledHTTPRequest needs a '_'
    240     // in 'dH'. This is a complement to the non-acronym case further down.
    241     if (was_uppercase && is_lowercase)
    242       needs_underscore = true;
    243     if (needs_underscore) {
    244       output += '_';
    245       needs_underscore = false;
    246     }
    247     output += c;
    248     // Handles the non-acronym case: transitioning from lower to upper case
    249     // requires an underscore when emitting the next character, e.g. didLoad
    250     // needs a '_' in 'dL'.
    251     if (!first_char && was_lowercase && is_uppercase)
    252       needs_underscore = true;
    253     was_lowercase = is_lowercase;
    254     was_uppercase = is_uppercase;
    255     first_char = false;
    256   }
    257   std::reverse(output.begin(), output.end());
    258   return output;
    259 }
    260 
    261 bool IsProbablyConst(const clang::VarDecl& decl,
    262                      const clang::ASTContext& context) {
    263   clang::QualType type = decl.getType();
    264   if (!type.isConstQualified())
    265     return false;
    266 
    267   if (type.isVolatileQualified())
    268     return false;
    269 
    270   // http://google.github.io/styleguide/cppguide.html#Constant_Names
    271   // Static variables that are const-qualified should use kConstantStyle naming.
    272   if (decl.getStorageDuration() == clang::SD_Static)
    273     return true;
    274 
    275   const clang::Expr* initializer = decl.getInit();
    276   if (!initializer)
    277     return false;
    278 
    279   // If the expression is dependent on a template input, then we are not
    280   // sure if it can be compile-time generated as calling isEvaluatable() is
    281   // not valid on |initializer|.
    282   // TODO(crbug.com/581218): We could probably look at each compiled
    283   // instantiation of the template and see if they are all compile-time
    284   // isEvaluable().
    285   if (initializer->isInstantiationDependent())
    286     return false;
    287 
    288   // If the expression can be evaluated at compile time, then it should have a
    289   // kFoo style name. Otherwise, not.
    290   return initializer->isEvaluatable(context);
    291 }
    292 
    293 AST_MATCHER_P(clang::QualType, hasString, std::string, ExpectedString) {
    294   return ExpectedString == Node.getAsString();
    295 }
    296 
    297 bool GetNameForDecl(const clang::FunctionDecl& decl,
    298                     clang::ASTContext& context,
    299                     std::string& name) {
    300   name = decl.getName().str();
    301   name[0] = clang::toUppercase(name[0]);
    302 
    303   // Given
    304   //   class Foo {};
    305   //   using Bar = Foo;
    306   //   Bar f1();  // <- |Bar| would be matched by hasString("Bar") below.
    307   //   Bar f2();  // <- |Bar| would be matched by hasName("Foo") below.
    308   // |type_with_same_name_as_function| matcher matches Bar and Foo return types.
    309   auto type_with_same_name_as_function = qualType(anyOf(
    310       hasString(name),  // hasString matches the type as spelled (Bar above).
    311       hasDeclaration(namedDecl(hasName(name)))));  // hasDeclaration matches
    312                                                    // resolved type (Foo above).
    313   // |type_containing_same_name_as_function| matcher will match all of the
    314   // return types below:
    315   // - Foo foo()  // Direct application of |type_with_same_name_as_function|.
    316   // - Foo* foo()  // |hasDescendant| traverses references/pointers.
    317   // - RefPtr<Foo> foo()  // |hasDescendant| traverses template arguments.
    318   auto type_containing_same_name_as_function =
    319       qualType(anyOf(type_with_same_name_as_function,
    320                      hasDescendant(type_with_same_name_as_function)));
    321   // https://crbug.com/582312: Prepend "Get" if method name conflicts with
    322   // return type.
    323   auto conflict_matcher =
    324       functionDecl(returns(type_containing_same_name_as_function));
    325   if (!match(conflict_matcher, decl, context).empty())
    326     name = "Get" + name;
    327 
    328   return true;
    329 }
    330 
    331 bool GetNameForDecl(const clang::EnumConstantDecl& decl,
    332                     clang::ASTContext& context,
    333                     std::string& name) {
    334   StringRef original_name = decl.getName();
    335 
    336   // If it's already correct leave it alone.
    337   if (original_name.size() >= 2 && original_name[0] == 'k' &&
    338       clang::isUppercase(original_name[1]))
    339     return false;
    340 
    341   bool is_shouty = true;
    342   for (char c : original_name) {
    343     if (!clang::isUppercase(c) && !clang::isDigit(c) && c != '_') {
    344       is_shouty = false;
    345       break;
    346     }
    347   }
    348 
    349   if (is_shouty)
    350     return false;
    351 
    352   name = 'k';  // k prefix on enum values.
    353   name += original_name;
    354   name[1] = clang::toUppercase(name[1]);
    355   return true;
    356 }
    357 
    358 bool GetNameForDecl(const clang::FieldDecl& decl,
    359                     clang::ASTContext& context,
    360                     std::string& name) {
    361   StringRef original_name = decl.getName();
    362   bool member_prefix = original_name.startswith(kBlinkFieldPrefix);
    363 
    364   StringRef rename_part = !member_prefix
    365                               ? original_name
    366                               : original_name.substr(strlen(kBlinkFieldPrefix));
    367   name = CamelCaseToUnderscoreCase(rename_part);
    368 
    369   // Assume that prefix of m_ was intentional and always replace it with a
    370   // suffix _.
    371   if (member_prefix && name.back() != '_')
    372     name += '_';
    373 
    374   return true;
    375 }
    376 
    377 bool GetNameForDecl(const clang::VarDecl& decl,
    378                     clang::ASTContext& context,
    379                     std::string& name) {
    380   StringRef original_name = decl.getName();
    381 
    382   // Nothing to do for unnamed parameters.
    383   if (clang::isa<clang::ParmVarDecl>(decl)) {
    384     if (original_name.empty())
    385       return false;
    386 
    387     // Check if |decl| and |decl.getLocation| are in sync.  We need to skip
    388     // out-of-sync ParmVarDecls to avoid renaming buggy ParmVarDecls that
    389     // 1) have decl.getLocation() pointing at a parameter declaration without a
    390     // name, but 2) have decl.getName() retained from a template specialization
    391     // of a method.  See also: https://llvm.org/bugs/show_bug.cgi?id=29145
    392     clang::SourceLocation loc =
    393         context.getSourceManager().getSpellingLoc(decl.getLocation());
    394     auto parents = context.getParents(decl);
    395     bool is_child_location_within_parent_source_range = std::all_of(
    396         parents.begin(), parents.end(),
    397         [&loc](const clang::ast_type_traits::DynTypedNode& parent) {
    398           clang::SourceLocation begin = parent.getSourceRange().getBegin();
    399           clang::SourceLocation end = parent.getSourceRange().getEnd();
    400           return (begin < loc) && (loc < end);
    401         });
    402     if (!is_child_location_within_parent_source_range)
    403       return false;
    404   }
    405 
    406   // static class members match against VarDecls. Blink style dictates that
    407   // these should be prefixed with `s_`, so strip that off. Also check for `m_`
    408   // and strip that off too, for code that accidentally uses the wrong prefix.
    409   if (original_name.startswith(kBlinkStaticMemberPrefix))
    410     original_name = original_name.substr(strlen(kBlinkStaticMemberPrefix));
    411   else if (original_name.startswith(kBlinkFieldPrefix))
    412     original_name = original_name.substr(strlen(kBlinkFieldPrefix));
    413 
    414   bool is_const = IsProbablyConst(decl, context);
    415   if (is_const) {
    416     // Don't try to rename constants that already conform to Chrome style.
    417     if (original_name.size() >= 2 && original_name[0] == 'k' &&
    418         clang::isUppercase(original_name[1]))
    419       return false;
    420 
    421     name = 'k';
    422     name.append(original_name.data(), original_name.size());
    423     name[1] = clang::toUppercase(name[1]);
    424   } else {
    425     name = CamelCaseToUnderscoreCase(original_name);
    426 
    427     // Non-const variables with static storage duration at namespace scope are
    428     // prefixed with `g_' to reduce the likelihood of a naming collision.
    429     const clang::DeclContext* decl_context = decl.getDeclContext();
    430     if (name.find("g_") != 0 && decl.hasGlobalStorage() &&
    431         decl_context->isNamespace())
    432       name.insert(0, "g_");
    433   }
    434 
    435   // Static members end with _ just like other members, but constants should
    436   // not.
    437   if (!is_const && decl.isStaticDataMember()) {
    438     name += '_';
    439   }
    440 
    441   return true;
    442 }
    443 
    444 bool GetNameForDecl(const clang::FunctionTemplateDecl& decl,
    445                     clang::ASTContext& context,
    446                     std::string& name) {
    447   clang::FunctionDecl* templated_function = decl.getTemplatedDecl();
    448   return GetNameForDecl(*templated_function, context, name);
    449 }
    450 
    451 bool GetNameForDecl(const clang::NamedDecl& decl,
    452                     clang::ASTContext& context,
    453                     std::string& name) {
    454   if (auto* function = clang::dyn_cast<clang::FunctionDecl>(&decl))
    455     return GetNameForDecl(*function, context, name);
    456   if (auto* var = clang::dyn_cast<clang::VarDecl>(&decl))
    457     return GetNameForDecl(*var, context, name);
    458   if (auto* field = clang::dyn_cast<clang::FieldDecl>(&decl))
    459     return GetNameForDecl(*field, context, name);
    460   if (auto* function_template =
    461           clang::dyn_cast<clang::FunctionTemplateDecl>(&decl))
    462     return GetNameForDecl(*function_template, context, name);
    463   if (auto* enumc = clang::dyn_cast<clang::EnumConstantDecl>(&decl))
    464     return GetNameForDecl(*enumc, context, name);
    465 
    466   return false;
    467 }
    468 
    469 bool GetNameForDecl(const clang::UsingDecl& decl,
    470                     clang::ASTContext& context,
    471                     std::string& name) {
    472   assert(decl.shadow_size() > 0);
    473 
    474   // If a using declaration's targeted declaration is a set of overloaded
    475   // functions, it can introduce multiple shadowed declarations. Just using the
    476   // first one is OK, since overloaded functions have the same name, by
    477   // definition.
    478   return GetNameForDecl(*decl.shadow_begin()->getTargetDecl(), context, name);
    479 }
    480 
    481 template <typename Type>
    482 struct TargetNodeTraits;
    483 
    484 template <>
    485 struct TargetNodeTraits<clang::NamedDecl> {
    486   static clang::SourceLocation GetLoc(const clang::NamedDecl& decl) {
    487     return decl.getLocation();
    488   }
    489   static const char* GetName() { return "decl"; }
    490   static const char* GetType() { return "NamedDecl"; }
    491 };
    492 
    493 template <>
    494 struct TargetNodeTraits<clang::MemberExpr> {
    495   static clang::SourceLocation GetLoc(const clang::MemberExpr& expr) {
    496     return expr.getMemberLoc();
    497   }
    498   static const char* GetName() { return "expr"; }
    499   static const char* GetType() { return "MemberExpr"; }
    500 };
    501 
    502 template <>
    503 struct TargetNodeTraits<clang::DeclRefExpr> {
    504   static clang::SourceLocation GetLoc(const clang::DeclRefExpr& expr) {
    505     return expr.getLocation();
    506   }
    507   static const char* GetName() { return "expr"; }
    508   static const char* GetType() { return "DeclRefExpr"; }
    509 };
    510 
    511 template <>
    512 struct TargetNodeTraits<clang::CXXCtorInitializer> {
    513   static clang::SourceLocation GetLoc(const clang::CXXCtorInitializer& init) {
    514     assert(init.isWritten());
    515     return init.getSourceLocation();
    516   }
    517   static const char* GetName() { return "initializer"; }
    518   static const char* GetType() { return "CXXCtorInitializer"; }
    519 };
    520 
    521 template <>
    522 struct TargetNodeTraits<clang::UnresolvedLookupExpr> {
    523   static clang::SourceLocation GetLoc(const clang::UnresolvedLookupExpr& expr) {
    524     return expr.getNameLoc();
    525   }
    526   static const char* GetName() { return "expr"; }
    527   static const char* GetType() { return "UnresolvedLookupExpr"; }
    528 };
    529 
    530 template <>
    531 struct TargetNodeTraits<clang::UnresolvedMemberExpr> {
    532   static clang::SourceLocation GetLoc(const clang::UnresolvedMemberExpr& expr) {
    533     return expr.getMemberLoc();
    534   }
    535   static const char* GetName() { return "expr"; }
    536   static const char* GetType() { return "UnresolvedMemberExpr"; }
    537 };
    538 
    539 template <typename DeclNode, typename TargetNode>
    540 class RewriterBase : public MatchFinder::MatchCallback {
    541  public:
    542   explicit RewriterBase(std::set<Replacement>* replacements)
    543       : replacements_(replacements) {}
    544 
    545   void run(const MatchFinder::MatchResult& result) override {
    546     const DeclNode* decl = result.Nodes.getNodeAs<DeclNode>("decl");
    547     // If false, there's no name to be renamed.
    548     if (!decl->getIdentifier())
    549       return;
    550     clang::SourceLocation decl_loc =
    551         TargetNodeTraits<clang::NamedDecl>::GetLoc(*decl);
    552     if (decl_loc.isMacroID()) {
    553       // Get the location of the spelling of the declaration. If token pasting
    554       // was used this will be in "scratch space" and we don't know how to get
    555       // from there back to/ the actual macro with the foo##bar text. So just
    556       // don't replace in that case.
    557       clang::SourceLocation spell =
    558           result.SourceManager->getSpellingLoc(decl_loc);
    559       if (strcmp(result.SourceManager->getBufferName(spell),
    560                  "<scratch space>") == 0)
    561         return;
    562     }
    563     clang::ASTContext* context = result.Context;
    564     std::string new_name;
    565     if (!GetNameForDecl(*decl, *context, new_name))
    566       return;  // If false, the name was not suitable for renaming.
    567     llvm::StringRef old_name = decl->getName();
    568     if (old_name == new_name)
    569       return;
    570     clang::SourceLocation loc = TargetNodeTraits<TargetNode>::GetLoc(
    571         *result.Nodes.getNodeAs<TargetNode>(
    572             TargetNodeTraits<TargetNode>::GetName()));
    573     clang::CharSourceRange range = clang::CharSourceRange::getTokenRange(loc);
    574     replacements_->emplace(*result.SourceManager, range, new_name);
    575     replacement_names_.emplace(old_name.str(), std::move(new_name));
    576   }
    577 
    578   const std::unordered_map<std::string, std::string>& replacement_names()
    579       const {
    580     return replacement_names_;
    581   }
    582 
    583  private:
    584   std::set<Replacement>* const replacements_;
    585   std::unordered_map<std::string, std::string> replacement_names_;
    586 };
    587 
    588 using FieldDeclRewriter = RewriterBase<clang::FieldDecl, clang::NamedDecl>;
    589 using VarDeclRewriter = RewriterBase<clang::VarDecl, clang::NamedDecl>;
    590 using MemberRewriter = RewriterBase<clang::FieldDecl, clang::MemberExpr>;
    591 using DeclRefRewriter = RewriterBase<clang::VarDecl, clang::DeclRefExpr>;
    592 using FieldDeclRefRewriter = RewriterBase<clang::FieldDecl, clang::DeclRefExpr>;
    593 using FunctionDeclRewriter =
    594     RewriterBase<clang::FunctionDecl, clang::NamedDecl>;
    595 using FunctionRefRewriter =
    596     RewriterBase<clang::FunctionDecl, clang::DeclRefExpr>;
    597 using ConstructorInitializerRewriter =
    598     RewriterBase<clang::FieldDecl, clang::CXXCtorInitializer>;
    599 
    600 using MethodDeclRewriter = RewriterBase<clang::CXXMethodDecl, clang::NamedDecl>;
    601 using MethodRefRewriter =
    602     RewriterBase<clang::CXXMethodDecl, clang::DeclRefExpr>;
    603 using MethodMemberRewriter =
    604     RewriterBase<clang::CXXMethodDecl, clang::MemberExpr>;
    605 
    606 using EnumConstantDeclRewriter =
    607     RewriterBase<clang::EnumConstantDecl, clang::NamedDecl>;
    608 using EnumConstantDeclRefRewriter =
    609     RewriterBase<clang::EnumConstantDecl, clang::DeclRefExpr>;
    610 
    611 using UnresolvedLookupRewriter =
    612     RewriterBase<clang::NamedDecl, clang::UnresolvedLookupExpr>;
    613 using UnresolvedMemberRewriter =
    614     RewriterBase<clang::NamedDecl, clang::UnresolvedMemberExpr>;
    615 
    616 using UsingDeclRewriter = RewriterBase<clang::UsingDecl, clang::NamedDecl>;
    617 
    618 }  // namespace
    619 
    620 static llvm::cl::extrahelp common_help(CommonOptionsParser::HelpMessage);
    621 
    622 int main(int argc, const char* argv[]) {
    623   // TODO(dcheng): Clang tooling should do this itself.
    624   // http://llvm.org/bugs/show_bug.cgi?id=21627
    625   llvm::InitializeNativeTarget();
    626   llvm::InitializeNativeTargetAsmParser();
    627   llvm::cl::OptionCategory category(
    628       "rewrite_to_chrome_style: convert Blink style to Chrome style.");
    629   CommonOptionsParser options(argc, argv, category);
    630   clang::tooling::ClangTool tool(options.getCompilations(),
    631                                  options.getSourcePathList());
    632 
    633   MatchFinder match_finder;
    634   std::set<Replacement> replacements;
    635 
    636   // Blink namespace matchers ========
    637   auto blink_namespace_decl =
    638       namespaceDecl(anyOf(hasName("blink"), hasName("WTF")),
    639                     hasParent(translationUnitDecl()));
    640 
    641   // Given top-level compilation unit:
    642   //   namespace WTF {
    643   //     void foo() {}
    644   //   }
    645   // matches |foo|.
    646   auto decl_under_blink_namespace = decl(hasAncestor(blink_namespace_decl));
    647 
    648   // Given top-level compilation unit:
    649   //   void WTF::function() {}
    650   //   void WTF::Class::method() {}
    651   // matches |WTF::function| and |WTF::Class::method| decls.
    652   auto decl_has_qualifier_to_blink_namespace =
    653       declaratorDecl(has(nestedNameSpecifier(
    654           hasTopLevelPrefix(specifiesNamespace(blink_namespace_decl)))));
    655 
    656   auto in_blink_namespace = decl(
    657       anyOf(decl_under_blink_namespace, decl_has_qualifier_to_blink_namespace,
    658             hasAncestor(decl_has_qualifier_to_blink_namespace)),
    659       unless(isExpansionInFileMatching(kGeneratedFileRegex)));
    660 
    661   // Field, variable, and enum declarations ========
    662   // Given
    663   //   int x;
    664   //   struct S {
    665   //     int y;
    666   //     enum { VALUE };
    667   //   };
    668   // matches |x|, |y|, and |VALUE|.
    669   auto field_decl_matcher = id("decl", fieldDecl(in_blink_namespace));
    670   auto is_type_trait_value =
    671       varDecl(hasName("value"), hasStaticStorageDuration(), isPublic(),
    672               hasType(isConstQualified()), hasType(type(anyOf(
    673                   booleanType(), enumType()))),
    674               unless(hasAncestor(recordDecl(
    675                   has(cxxMethodDecl(isUserProvided(), isInstanceMethod()))))));
    676   auto var_decl_matcher =
    677       id("decl", varDecl(in_blink_namespace, unless(is_type_trait_value)));
    678   auto enum_member_decl_matcher =
    679       id("decl", enumConstantDecl(in_blink_namespace));
    680 
    681   FieldDeclRewriter field_decl_rewriter(&replacements);
    682   match_finder.addMatcher(field_decl_matcher, &field_decl_rewriter);
    683 
    684   VarDeclRewriter var_decl_rewriter(&replacements);
    685   match_finder.addMatcher(var_decl_matcher, &var_decl_rewriter);
    686 
    687   EnumConstantDeclRewriter enum_member_decl_rewriter(&replacements);
    688   match_finder.addMatcher(enum_member_decl_matcher, &enum_member_decl_rewriter);
    689 
    690   // Field, variable, and enum references ========
    691   // Given
    692   //   bool x = true;
    693   //   if (x) {
    694   //     ...
    695   //   }
    696   // matches |x| in if (x).
    697   auto member_matcher = id(
    698       "expr",
    699       memberExpr(
    700           member(field_decl_matcher),
    701           // Needed to avoid matching member references in functions (which will
    702           // be an ancestor of the member reference) synthesized by the
    703           // compiler, such as a synthesized copy constructor.
    704           // This skips explicitly defaulted functions as well, but that's OK:
    705           // there's nothing interesting to rewrite in those either.
    706           unless(hasAncestor(functionDecl(isDefaulted())))));
    707   auto decl_ref_matcher = id("expr", declRefExpr(to(var_decl_matcher)));
    708   auto enum_member_ref_matcher =
    709       id("expr", declRefExpr(to(enum_member_decl_matcher)));
    710 
    711   MemberRewriter member_rewriter(&replacements);
    712   match_finder.addMatcher(member_matcher, &member_rewriter);
    713 
    714   DeclRefRewriter decl_ref_rewriter(&replacements);
    715   match_finder.addMatcher(decl_ref_matcher, &decl_ref_rewriter);
    716 
    717   EnumConstantDeclRefRewriter enum_member_ref_rewriter(&replacements);
    718   match_finder.addMatcher(enum_member_ref_matcher, &enum_member_ref_rewriter);
    719 
    720   // Member references in a non-member context ========
    721   // Given
    722   //   struct S {
    723   //     typedef int U::*UnspecifiedBoolType;
    724   //     operator UnspecifiedBoolType() { return s_ ? &U::s_ : 0; }
    725   //     int s_;
    726   //   };
    727   // matches |&U::s_| but not |s_|.
    728   auto member_ref_matcher = id("expr", declRefExpr(to(field_decl_matcher)));
    729 
    730   FieldDeclRefRewriter member_ref_rewriter(&replacements);
    731   match_finder.addMatcher(member_ref_matcher, &member_ref_rewriter);
    732 
    733   // Non-method function declarations ========
    734   // Given
    735   //   void f();
    736   //   struct S {
    737   //     void g();
    738   //   };
    739   // matches |f| but not |g|.
    740   auto function_decl_matcher = id(
    741       "decl",
    742       functionDecl(
    743           unless(anyOf(
    744               // Methods are covered by the method matchers.
    745               cxxMethodDecl(),
    746               // Out-of-line overloaded operators have special names and should
    747               // never be renamed.
    748               isOverloadedOperator(),
    749               // Must be checked after filtering out overloaded operators to
    750               // prevent asserts about the identifier not being a simple name.
    751               isBlacklistedFunction())),
    752           in_blink_namespace));
    753   FunctionDeclRewriter function_decl_rewriter(&replacements);
    754   match_finder.addMatcher(function_decl_matcher, &function_decl_rewriter);
    755 
    756   // Non-method function references ========
    757   // Given
    758   //   f();
    759   //   void (*p)() = &f;
    760   // matches |f()| and |&f|.
    761   auto function_ref_matcher = id(
    762       "expr", declRefExpr(to(function_decl_matcher),
    763                           // Ignore template substitutions.
    764                           unless(hasAncestor(substNonTypeTemplateParmExpr()))));
    765   FunctionRefRewriter function_ref_rewriter(&replacements);
    766   match_finder.addMatcher(function_ref_matcher, &function_ref_rewriter);
    767 
    768   // Method declarations ========
    769   // Given
    770   //   struct S {
    771   //     void g();
    772   //   };
    773   // matches |g|.
    774   // For a method to be considered for rewrite, it must not override something
    775   // that we're not rewriting. Any methods that we would not normally consider
    776   // but that override something we are rewriting should also be rewritten. So
    777   // we use includeAllOverriddenMethods() to check these rules not just for the
    778   // method being matched but for the methods it overrides also.
    779   auto is_blink_method = includeAllOverriddenMethods(
    780       allOf(in_blink_namespace, unless(isBlacklistedMethod())));
    781   auto method_decl_matcher = id(
    782       "decl",
    783       cxxMethodDecl(
    784           unless(anyOf(
    785               // Overloaded operators have special names and should never be
    786               // renamed.
    787               isOverloadedOperator(),
    788               // Similarly, constructors, destructors, and conversion
    789               // functions should not be considered for renaming.
    790               cxxConstructorDecl(), cxxDestructorDecl(), cxxConversionDecl())),
    791           // Check this last after excluding things, to avoid
    792           // asserts about overriding non-blink and blink for the
    793           // same method.
    794           is_blink_method));
    795   MethodDeclRewriter method_decl_rewriter(&replacements);
    796   match_finder.addMatcher(method_decl_matcher, &method_decl_rewriter);
    797 
    798   // Method references in a non-member context ========
    799   // Given
    800   //   S s;
    801   //   s.g();
    802   //   void (S::*p)() = &S::g;
    803   // matches |&S::g| but not |s.g()|.
    804   auto method_ref_matcher = id(
    805       "expr", declRefExpr(to(method_decl_matcher),
    806                           // Ignore template substitutions.
    807                           unless(hasAncestor(substNonTypeTemplateParmExpr()))));
    808 
    809   MethodRefRewriter method_ref_rewriter(&replacements);
    810   match_finder.addMatcher(method_ref_matcher, &method_ref_rewriter);
    811 
    812   // Method references in a member context ========
    813   // Given
    814   //   S s;
    815   //   s.g();
    816   //   void (S::*p)() = &S::g;
    817   // matches |s.g()| but not |&S::g|.
    818   auto method_member_matcher =
    819       id("expr", memberExpr(member(method_decl_matcher)));
    820 
    821   MethodMemberRewriter method_member_rewriter(&replacements);
    822   match_finder.addMatcher(method_member_matcher, &method_member_rewriter);
    823 
    824   // Initializers ========
    825   // Given
    826   //   struct S {
    827   //     int x;
    828   //     S() : x(2) {}
    829   //   };
    830   // matches each initializer in the constructor for S.
    831   auto constructor_initializer_matcher =
    832       cxxConstructorDecl(forEachConstructorInitializer(id(
    833           "initializer",
    834           cxxCtorInitializer(forAnyField(field_decl_matcher), isWritten()))));
    835 
    836   ConstructorInitializerRewriter constructor_initializer_rewriter(
    837       &replacements);
    838   match_finder.addMatcher(constructor_initializer_matcher,
    839                           &constructor_initializer_rewriter);
    840 
    841   // Unresolved lookup expressions ========
    842   // Given
    843   //   template<typename T> void F(T) { }
    844   //   template<void G(T)> H(T) { }
    845   //   H<F<int>>(...);
    846   // matches |F| in |H<F<int>>|.
    847   //
    848   // UnresolvedLookupExprs are similar to DeclRefExprs that reference a
    849   // FunctionDecl, but are used when a candidate FunctionDecl can't be selected.
    850   // This commonly happens inside uninstantiated template definitions for one of
    851   // two reasons:
    852   //
    853   // 1. If the candidate declaration is a dependent FunctionTemplateDecl, the
    854   //    actual overload can't be selected until template instantiation time.
    855   // 2. Alternatively, there might be multiple declarations in the candidate set
    856   //    if the candidate function has overloads. If any of the function
    857   //    arguments has a dependent type, then the actual overload can't be
    858   //    selected until instantiation time either.
    859   //
    860   // Another instance where UnresolvedLookupExprs can appear is in a template
    861   // argument list, like the provided example.
    862   auto function_template_decl_matcher =
    863       id("decl", functionTemplateDecl(templatedDecl(function_decl_matcher)));
    864   auto method_template_decl_matcher =
    865       id("decl", functionTemplateDecl(templatedDecl(method_decl_matcher)));
    866   auto unresolved_lookup_matcher = expr(id(
    867       "expr",
    868       unresolvedLookupExpr(
    869           // In order to automatically rename an unresolved lookup, the lookup
    870           // candidates must either all be Blink functions/function templates or
    871           // all be Blink methods/method templates. Otherwise, we might end up
    872           // in a situation where the naming could change depending on the
    873           // selected candidate.
    874           anyOf(allOverloadsMatch(anyOf(function_decl_matcher,
    875                                         function_template_decl_matcher)),
    876                 // Note: this matches references to methods in a non-member
    877                 // context, e.g. Template<&Class::Method>. This and the
    878                 // UnresolvedMemberExpr matcher below are analogous to how the
    879                 // rewriter has both a MemberRefRewriter matcher to rewrite
    880                 // &T::method and a MethodMemberRewriter matcher to rewriter
    881                 // t.method().
    882                 allOverloadsMatch(anyOf(method_decl_matcher,
    883                                         method_template_decl_matcher))))));
    884   UnresolvedLookupRewriter unresolved_lookup_rewriter(&replacements);
    885   match_finder.addMatcher(unresolved_lookup_matcher,
    886                           &unresolved_lookup_rewriter);
    887 
    888   // Unresolved member expressions ========
    889   // Similar to unresolved lookup expressions, but for methods in a member
    890   // context, e.g. var_with_templated_type.Method().
    891   auto unresolved_member_matcher = expr(id(
    892       "expr",
    893       unresolvedMemberExpr(
    894           // Similar to UnresolvedLookupExprs, all the candidate methods must be
    895           // Blink methods/method templates.
    896           allOverloadsMatch(
    897               anyOf(method_decl_matcher, method_template_decl_matcher)))));
    898   UnresolvedMemberRewriter unresolved_member_rewriter(&replacements);
    899   match_finder.addMatcher(unresolved_member_matcher,
    900                           &unresolved_member_rewriter);
    901 
    902   // Using declarations ========
    903   // Given
    904   //   using blink::X;
    905   // matches |using blink::X|.
    906   auto using_decl_matcher = id(
    907       "decl", usingDecl(hasAnyUsingShadowDecl(hasTargetDecl(anyOf(
    908                   var_decl_matcher, field_decl_matcher, function_decl_matcher,
    909                   method_decl_matcher, function_template_decl_matcher,
    910                   method_template_decl_matcher, enum_member_decl_matcher)))));
    911   UsingDeclRewriter using_decl_rewriter(&replacements);
    912   match_finder.addMatcher(using_decl_matcher, &using_decl_rewriter);
    913 
    914   std::unique_ptr<clang::tooling::FrontendActionFactory> factory =
    915       clang::tooling::newFrontendActionFactory(&match_finder);
    916   int result = tool.run(factory.get());
    917   if (result != 0)
    918     return result;
    919 
    920 #if defined(_WIN32)
    921   HANDLE lockfd = CreateFile("rewrite-sym.lock", GENERIC_READ, FILE_SHARE_READ,
    922                              NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    923   OVERLAPPED overlapped = {};
    924   LockFileEx(lockfd, LOCKFILE_EXCLUSIVE_LOCK, 0, 1, 0, &overlapped);
    925 #else
    926   int lockfd = open("rewrite-sym.lock", O_RDWR | O_CREAT, 0666);
    927   while (flock(lockfd, LOCK_EX)) {  // :D
    928   }
    929 #endif
    930 
    931   std::ofstream replacement_db_file("rewrite-sym.txt",
    932                                     std::ios_base::out | std::ios_base::app);
    933   for (const auto& p : field_decl_rewriter.replacement_names())
    934     replacement_db_file << "var:" << p.first << ":" << p.second << "\n";
    935   for (const auto& p : var_decl_rewriter.replacement_names())
    936     replacement_db_file << "var:" << p.first << ":" << p.second << "\n";
    937   for (const auto& p : enum_member_decl_rewriter.replacement_names())
    938     replacement_db_file << "enu:" << p.first << ":" << p.second << "\n";
    939   for (const auto& p : function_decl_rewriter.replacement_names())
    940     replacement_db_file << "fun:" << p.first << ":" << p.second << "\n";
    941   for (const auto& p : method_decl_rewriter.replacement_names())
    942     replacement_db_file << "fun:" << p.first << ":" << p.second << "\n";
    943   replacement_db_file.close();
    944 
    945 #if defined(_WIN32)
    946   UnlockFileEx(lockfd, 0, 1, 0, &overlapped);
    947   CloseHandle(lockfd);
    948 #else
    949   flock(lockfd, LOCK_UN);
    950   close(lockfd);
    951 #endif
    952 
    953   // Serialization format is documented in tools/clang/scripts/run_tool.py
    954   llvm::outs() << "==== BEGIN EDITS ====\n";
    955   for (const auto& r : replacements) {
    956     std::string replacement_text = r.getReplacementText().str();
    957     std::replace(replacement_text.begin(), replacement_text.end(), '\n', '\0');
    958     llvm::outs() << "r:::" << r.getFilePath() << ":::" << r.getOffset()
    959                  << ":::" << r.getLength() << ":::" << replacement_text << "\n";
    960   }
    961   llvm::outs() << "==== END EDITS ====\n";
    962 
    963   return 0;
    964 }
    965