| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 // | 4 // |
| 5 // Changes Blink-style names to Chrome-style names. Currently transforms: | 5 // Changes Blink-style names to Chrome-style names. Currently transforms: |
| 6 // fields: | 6 // fields: |
| 7 // int m_operationCount => int operation_count_ | 7 // int m_operationCount => int operation_count_ |
| 8 // variables (including parameters): | 8 // variables (including parameters): |
| 9 // int mySuperVariable => int my_super_variable | 9 // int mySuperVariable => int my_super_variable |
| 10 // constants: | 10 // constants: |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 123 return false; | 123 return false; |
| 124 } | 124 } |
| 125 | 125 |
| 126 class MethodBlocklist { | 126 class MethodBlocklist { |
| 127 public: | 127 public: |
| 128 explicit MethodBlocklist(const std::string& filepath) { | 128 explicit MethodBlocklist(const std::string& filepath) { |
| 129 if (!filepath.empty()) | 129 if (!filepath.empty()) |
| 130 ParseInputFile(filepath); | 130 ParseInputFile(filepath); |
| 131 } | 131 } |
| 132 | 132 |
| 133 bool Contains(const clang::CXXMethodDecl& method) const { | 133 bool Contains(const clang::FunctionDecl& method) const { |
| 134 auto it = method_to_class_to_args_.find(method.getName()); | 134 auto it = method_to_class_to_args_.find(method.getName()); |
| 135 if (it == method_to_class_to_args_.end()) | 135 if (it == method_to_class_to_args_.end()) |
| 136 return false; | 136 return false; |
| 137 | 137 |
| 138 const clang::CXXRecordDecl* actual_class = method.getParent(); | 138 // |method_context| is either |
| 139 assert(actual_class && | 139 // 1) a CXXRecordDecl (i.e. blink::Document) or |
| 140 "Hopefully |getParent()| can find the class even for non-inlined " | 140 // 2) a NamespaceDecl (i.e. blink::DOMWindowTimers). |
| 141 "method definitions (where CXXRecordDecl is not a parent AST node " | 141 const clang::NamedDecl* method_context = |
| 142 "of CXXMethodDecl."); | 142 clang::dyn_cast<clang::NamedDecl>(method.getDeclContext()); |
| 143 if (!method_context) |
| 144 return false; |
| 143 | 145 |
| 144 const llvm::StringMap<std::set<unsigned>>& class_to_args = it->second; | 146 const llvm::StringMap<std::set<unsigned>>& class_to_args = it->second; |
| 145 auto it2 = class_to_args.find(actual_class->getName()); | 147 auto it2 = class_to_args.find(method_context->getName()); |
| 146 if (it2 == class_to_args.end()) | 148 if (it2 == class_to_args.end()) |
| 147 return false; | 149 return false; |
| 148 | 150 |
| 149 const std::set<unsigned>& arg_counts = it2->second; | 151 const std::set<unsigned>& arg_counts = it2->second; |
| 150 unsigned method_param_count = method.param_size(); | 152 unsigned method_param_count = method.param_size(); |
| 151 unsigned method_non_optional_param_count = method_param_count; | 153 unsigned method_non_optional_param_count = method_param_count; |
| 152 for (const clang::ParmVarDecl* param : method.parameters()) { | 154 for (const clang::ParmVarDecl* param : method.parameters()) { |
| 153 if (param->hasInit()) | 155 if (param->hasInit()) |
| 154 method_non_optional_param_count--; | 156 method_non_optional_param_count--; |
| 155 } | 157 } |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 218 method_to_class_to_args_[method_name][class_name].insert( | 220 method_to_class_to_args_[method_name][class_name].insert( |
| 219 number_of_method_args); | 221 number_of_method_args); |
| 220 } | 222 } |
| 221 } | 223 } |
| 222 | 224 |
| 223 // Stores methods to blacklist in a map: | 225 // Stores methods to blacklist in a map: |
| 224 // method name -> class name -> set of all allowed numbers of arguments. | 226 // method name -> class name -> set of all allowed numbers of arguments. |
| 225 llvm::StringMap<llvm::StringMap<std::set<unsigned>>> method_to_class_to_args_; | 227 llvm::StringMap<llvm::StringMap<std::set<unsigned>>> method_to_class_to_args_; |
| 226 }; | 228 }; |
| 227 | 229 |
| 228 AST_MATCHER_P(clang::CXXMethodDecl, | 230 AST_MATCHER_P(clang::FunctionDecl, |
| 229 isBlocklistedMethod, | 231 isBlocklistedMethod, |
| 230 MethodBlocklist, | 232 MethodBlocklist, |
| 231 Blocklist) { | 233 Blocklist) { |
| 232 return Blocklist.Contains(Node); | 234 return Blocklist.Contains(Node); |
| 233 } | 235 } |
| 234 | 236 |
| 235 // If |InnerMatcher| matches |top|, then the returned matcher will match: | 237 // If |InnerMatcher| matches |top|, then the returned matcher will match: |
| 236 // - |top::function| | 238 // - |top::function| |
| 237 // - |top::Class::method| | 239 // - |top::Class::method| |
| 238 // - |top::internal::Class::method| | 240 // - |top::internal::Class::method| |
| (...skipping 1146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1385 // TODO(dcheng): Clang tooling should do this itself. | 1387 // TODO(dcheng): Clang tooling should do this itself. |
| 1386 // http://llvm.org/bugs/show_bug.cgi?id=21627 | 1388 // http://llvm.org/bugs/show_bug.cgi?id=21627 |
| 1387 llvm::InitializeNativeTarget(); | 1389 llvm::InitializeNativeTarget(); |
| 1388 llvm::InitializeNativeTargetAsmParser(); | 1390 llvm::InitializeNativeTargetAsmParser(); |
| 1389 llvm::cl::OptionCategory category( | 1391 llvm::cl::OptionCategory category( |
| 1390 "rewrite_to_chrome_style: convert Blink style to Chrome style."); | 1392 "rewrite_to_chrome_style: convert Blink style to Chrome style."); |
| 1391 llvm::cl::opt<std::string> blocklisted_methods_file( | 1393 llvm::cl::opt<std::string> blocklisted_methods_file( |
| 1392 kMethodBlocklistParamName, llvm::cl::value_desc("filepath"), | 1394 kMethodBlocklistParamName, llvm::cl::value_desc("filepath"), |
| 1393 llvm::cl::desc("file listing methods to be blocked (not renamed)")); | 1395 llvm::cl::desc("file listing methods to be blocked (not renamed)")); |
| 1394 CommonOptionsParser options(argc, argv, category); | 1396 CommonOptionsParser options(argc, argv, category); |
| 1397 MethodBlocklist method_blocklist(blocklisted_methods_file); |
| 1395 clang::tooling::ClangTool tool(options.getCompilations(), | 1398 clang::tooling::ClangTool tool(options.getCompilations(), |
| 1396 options.getSourcePathList()); | 1399 options.getSourcePathList()); |
| 1397 | 1400 |
| 1398 MatchFinder match_finder; | 1401 MatchFinder match_finder; |
| 1399 std::set<Replacement> replacements; | 1402 std::set<Replacement> replacements; |
| 1400 | 1403 |
| 1401 // Blink namespace matchers ======== | 1404 // Blink namespace matchers ======== |
| 1402 auto blink_namespace_decl = | 1405 auto blink_namespace_decl = |
| 1403 namespaceDecl(anyOf(hasName("blink"), hasName("WTF")), | 1406 namespaceDecl(anyOf(hasName("blink"), hasName("WTF")), |
| 1404 hasParent(translationUnitDecl())); | 1407 hasParent(translationUnitDecl())); |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1506 "decl", | 1509 "decl", |
| 1507 functionDecl( | 1510 functionDecl( |
| 1508 unless(anyOf( | 1511 unless(anyOf( |
| 1509 // Methods are covered by the method matchers. | 1512 // Methods are covered by the method matchers. |
| 1510 cxxMethodDecl(), | 1513 cxxMethodDecl(), |
| 1511 // Out-of-line overloaded operators have special names and should | 1514 // Out-of-line overloaded operators have special names and should |
| 1512 // never be renamed. | 1515 // never be renamed. |
| 1513 isOverloadedOperator(), | 1516 isOverloadedOperator(), |
| 1514 // Must be checked after filtering out overloaded operators to | 1517 // Must be checked after filtering out overloaded operators to |
| 1515 // prevent asserts about the identifier not being a simple name. | 1518 // prevent asserts about the identifier not being a simple name. |
| 1516 isBlacklistedFunction())), | 1519 isBlacklistedFunction(), |
| 1520 // Functions that look like blocked static methods. |
| 1521 isBlocklistedMethod(method_blocklist))), |
| 1517 in_blink_namespace)); | 1522 in_blink_namespace)); |
| 1518 FunctionDeclRewriter function_decl_rewriter(&replacements); | 1523 FunctionDeclRewriter function_decl_rewriter(&replacements); |
| 1519 match_finder.addMatcher(function_decl_matcher, &function_decl_rewriter); | 1524 match_finder.addMatcher(function_decl_matcher, &function_decl_rewriter); |
| 1520 | 1525 |
| 1521 // Non-method function references ======== | 1526 // Non-method function references ======== |
| 1522 // Given | 1527 // Given |
| 1523 // f(); | 1528 // f(); |
| 1524 // void (*p)() = &f; | 1529 // void (*p)() = &f; |
| 1525 // matches |f()| and |&f|. | 1530 // matches |f()| and |&f|. |
| 1526 auto function_ref_matcher = id( | 1531 auto function_ref_matcher = id( |
| 1527 "expr", declRefExpr(to(function_decl_matcher), | 1532 "expr", declRefExpr(to(function_decl_matcher), |
| 1528 // Ignore template substitutions. | 1533 // Ignore template substitutions. |
| 1529 unless(hasAncestor(substNonTypeTemplateParmExpr())))); | 1534 unless(hasAncestor(substNonTypeTemplateParmExpr())))); |
| 1530 FunctionRefRewriter function_ref_rewriter(&replacements); | 1535 FunctionRefRewriter function_ref_rewriter(&replacements); |
| 1531 match_finder.addMatcher(function_ref_matcher, &function_ref_rewriter); | 1536 match_finder.addMatcher(function_ref_matcher, &function_ref_rewriter); |
| 1532 | 1537 |
| 1533 // Method declarations ======== | 1538 // Method declarations ======== |
| 1534 // Given | 1539 // Given |
| 1535 // struct S { | 1540 // struct S { |
| 1536 // void g(); | 1541 // void g(); |
| 1537 // }; | 1542 // }; |
| 1538 // matches |g|. | 1543 // matches |g|. |
| 1539 // For a method to be considered for rewrite, it must not override something | 1544 // For a method to be considered for rewrite, it must not override something |
| 1540 // that we're not rewriting. Any methods that we would not normally consider | 1545 // that we're not rewriting. Any methods that we would not normally consider |
| 1541 // but that override something we are rewriting should also be rewritten. So | 1546 // but that override something we are rewriting should also be rewritten. So |
| 1542 // we use includeAllOverriddenMethods() to check these rules not just for the | 1547 // we use includeAllOverriddenMethods() to check these rules not just for the |
| 1543 // method being matched but for the methods it overrides also. | 1548 // method being matched but for the methods it overrides also. |
| 1544 MethodBlocklist method_blocklist(blocklisted_methods_file); | |
| 1545 auto is_blink_method = includeAllOverriddenMethods( | 1549 auto is_blink_method = includeAllOverriddenMethods( |
| 1546 allOf(in_blink_namespace, unless(isBlacklistedMethod()), | 1550 allOf(in_blink_namespace, |
| 1547 unless(isBlocklistedMethod(method_blocklist)))); | 1551 unless(anyOf(isBlacklistedMethod(), |
| 1552 isBlocklistedMethod(method_blocklist))))); |
| 1548 auto method_decl_matcher = id( | 1553 auto method_decl_matcher = id( |
| 1549 "decl", | 1554 "decl", |
| 1550 cxxMethodDecl( | 1555 cxxMethodDecl( |
| 1551 unless(anyOf( | 1556 unless(anyOf( |
| 1552 // Overloaded operators have special names and should never be | 1557 // Overloaded operators have special names and should never be |
| 1553 // renamed. | 1558 // renamed. |
| 1554 isOverloadedOperator(), | 1559 isOverloadedOperator(), |
| 1555 // Similarly, constructors, destructors, and conversion | 1560 // Similarly, constructors, destructors, and conversion |
| 1556 // functions should not be considered for renaming. | 1561 // functions should not be considered for renaming. |
| 1557 cxxConstructorDecl(), cxxDestructorDecl(), cxxConversionDecl())), | 1562 cxxConstructorDecl(), cxxDestructorDecl(), cxxConversionDecl())), |
| (...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1785 for (const auto& r : replacements) { | 1790 for (const auto& r : replacements) { |
| 1786 std::string replacement_text = r.getReplacementText().str(); | 1791 std::string replacement_text = r.getReplacementText().str(); |
| 1787 std::replace(replacement_text.begin(), replacement_text.end(), '\n', '\0'); | 1792 std::replace(replacement_text.begin(), replacement_text.end(), '\n', '\0'); |
| 1788 llvm::outs() << "r:::" << r.getFilePath() << ":::" << r.getOffset() | 1793 llvm::outs() << "r:::" << r.getFilePath() << ":::" << r.getOffset() |
| 1789 << ":::" << r.getLength() << ":::" << replacement_text << "\n"; | 1794 << ":::" << r.getLength() << ":::" << replacement_text << "\n"; |
| 1790 } | 1795 } |
| 1791 llvm::outs() << "==== END EDITS ====\n"; | 1796 llvm::outs() << "==== END EDITS ====\n"; |
| 1792 | 1797 |
| 1793 return 0; | 1798 return 0; |
| 1794 } | 1799 } |
| OLD | NEW |