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