| 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 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 44 using clang::tooling::CommonOptionsParser; | 44 using clang::tooling::CommonOptionsParser; |
| 45 using clang::tooling::Replacement; | 45 using clang::tooling::Replacement; |
| 46 using llvm::StringRef; | 46 using llvm::StringRef; |
| 47 | 47 |
| 48 namespace { | 48 namespace { |
| 49 | 49 |
| 50 const char kBlinkFieldPrefix[] = "m_"; | 50 const char kBlinkFieldPrefix[] = "m_"; |
| 51 const char kBlinkStaticMemberPrefix[] = "s_"; | 51 const char kBlinkStaticMemberPrefix[] = "s_"; |
| 52 const char kGeneratedFileRegex[] = "^gen/|/gen/"; | 52 const char kGeneratedFileRegex[] = "^gen/|/gen/"; |
| 53 | 53 |
| 54 template <typename MatcherType, typename NodeType> |
| 55 bool IsMatching(const MatcherType& matcher, |
| 56 const NodeType& node, |
| 57 clang::ASTContext& context) { |
| 58 return !match(matcher, node, context).empty(); |
| 59 } |
| 60 |
| 54 const clang::ast_matchers::internal:: | 61 const clang::ast_matchers::internal:: |
| 55 VariadicDynCastAllOfMatcher<clang::Expr, clang::UnresolvedMemberExpr> | 62 VariadicDynCastAllOfMatcher<clang::Expr, clang::UnresolvedMemberExpr> |
| 56 unresolvedMemberExpr; | 63 unresolvedMemberExpr; |
| 57 | 64 |
| 58 AST_MATCHER(clang::FunctionDecl, isOverloadedOperator) { | 65 AST_MATCHER(clang::FunctionDecl, isOverloadedOperator) { |
| 59 return Node.isOverloadedOperator(); | 66 return Node.isOverloadedOperator(); |
| 60 } | 67 } |
| 61 | 68 |
| 62 AST_MATCHER(clang::CXXMethodDecl, isInstanceMethod) { | 69 AST_MATCHER(clang::CXXMethodDecl, isInstanceMethod) { |
| 63 return Node.isInstance(); | 70 return Node.isInstance(); |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 205 // Subclasses of InspectorAgent will subclass "disable()" from both blink and | 212 // Subclasses of InspectorAgent will subclass "disable()" from both blink and |
| 206 // from gen/, which is problematic, but DevTools folks don't want to rename | 213 // 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. | 214 // it or split this up. So don't rename it at all. |
| 208 if (name.equals("disable") && | 215 if (name.equals("disable") && |
| 209 IsMethodOverrideOf(decl, "blink::InspectorAgent")) | 216 IsMethodOverrideOf(decl, "blink::InspectorAgent")) |
| 210 return true; | 217 return true; |
| 211 | 218 |
| 212 return false; | 219 return false; |
| 213 } | 220 } |
| 214 | 221 |
| 222 bool IsBlacklistedFunctionOrMethodName(llvm::StringRef name) { |
| 223 static const char* kBlacklistedNames[] = { |
| 224 // From IsBlacklistedFunction: |
| 225 "swap", |
| 226 // From IsBlacklistedMethod: |
| 227 "trace", "traceImpl", "lock", "unlock", "try_lock", "begin", "end", |
| 228 "rbegin", "rend", "disable", |
| 229 }; |
| 230 for (const auto& b : kBlacklistedNames) { |
| 231 if (name == b) |
| 232 return true; |
| 233 } |
| 234 return false; |
| 235 } |
| 236 |
| 215 AST_MATCHER(clang::FunctionDecl, isBlacklistedFunction) { | 237 AST_MATCHER(clang::FunctionDecl, isBlacklistedFunction) { |
| 216 return IsBlacklistedFunction(Node); | 238 return IsBlacklistedFunction(Node); |
| 217 } | 239 } |
| 218 | 240 |
| 219 AST_MATCHER(clang::CXXMethodDecl, isBlacklistedMethod) { | 241 AST_MATCHER(clang::CXXMethodDecl, isBlacklistedMethod) { |
| 220 return IsBlacklistedMethod(Node); | 242 return IsBlacklistedMethod(Node); |
| 221 } | 243 } |
| 222 | 244 |
| 223 // Helper to convert from a camelCaseName to camel_case_name. It uses some | 245 // 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. | 246 // heuristics to try to handle acronyms in camel case names correctly. |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 315 // - Foo foo() // Direct application of |type_with_same_name_as_function|. | 337 // - Foo foo() // Direct application of |type_with_same_name_as_function|. |
| 316 // - Foo* foo() // |hasDescendant| traverses references/pointers. | 338 // - Foo* foo() // |hasDescendant| traverses references/pointers. |
| 317 // - RefPtr<Foo> foo() // |hasDescendant| traverses template arguments. | 339 // - RefPtr<Foo> foo() // |hasDescendant| traverses template arguments. |
| 318 auto type_containing_same_name_as_function = | 340 auto type_containing_same_name_as_function = |
| 319 qualType(anyOf(type_with_same_name_as_function, | 341 qualType(anyOf(type_with_same_name_as_function, |
| 320 hasDescendant(type_with_same_name_as_function))); | 342 hasDescendant(type_with_same_name_as_function))); |
| 321 // https://crbug.com/582312: Prepend "Get" if method name conflicts with | 343 // https://crbug.com/582312: Prepend "Get" if method name conflicts with |
| 322 // return type. | 344 // return type. |
| 323 auto conflict_matcher = | 345 auto conflict_matcher = |
| 324 functionDecl(returns(type_containing_same_name_as_function)); | 346 functionDecl(returns(type_containing_same_name_as_function)); |
| 325 if (!match(conflict_matcher, decl, context).empty()) | 347 if (IsMatching(conflict_matcher, decl, context)) |
| 326 name = "Get" + name; | 348 name = "Get" + name; |
| 327 | 349 |
| 328 return true; | 350 return true; |
| 329 } | 351 } |
| 330 | 352 |
| 331 bool GetNameForDecl(const clang::EnumConstantDecl& decl, | 353 bool GetNameForDecl(const clang::EnumConstantDecl& decl, |
| 332 clang::ASTContext& context, | 354 clang::ASTContext& context, |
| 333 std::string& name) { | 355 std::string& name) { |
| 334 StringRef original_name = decl.getName(); | 356 StringRef original_name = decl.getName(); |
| 335 | 357 |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 529 | 551 |
| 530 template <> | 552 template <> |
| 531 struct TargetNodeTraits<clang::UnresolvedMemberExpr> { | 553 struct TargetNodeTraits<clang::UnresolvedMemberExpr> { |
| 532 static clang::SourceLocation GetLoc(const clang::UnresolvedMemberExpr& expr) { | 554 static clang::SourceLocation GetLoc(const clang::UnresolvedMemberExpr& expr) { |
| 533 return expr.getMemberLoc(); | 555 return expr.getMemberLoc(); |
| 534 } | 556 } |
| 535 static const char* GetName() { return "expr"; } | 557 static const char* GetName() { return "expr"; } |
| 536 static const char* GetType() { return "UnresolvedMemberExpr"; } | 558 static const char* GetType() { return "UnresolvedMemberExpr"; } |
| 537 }; | 559 }; |
| 538 | 560 |
| 539 template <typename DeclNode, typename TargetNode> | 561 template <> |
| 562 struct TargetNodeTraits<clang::UnresolvedUsingValueDecl> { |
| 563 static clang::SourceLocation GetLoc( |
| 564 const clang::UnresolvedUsingValueDecl& decl) { |
| 565 return decl.getNameInfo().getLoc(); |
| 566 } |
| 567 static const char* GetName() { return "decl"; } |
| 568 static const char* GetType() { return "UnresolvedUsingValueDecl"; } |
| 569 }; |
| 570 |
| 571 template <typename TargetNode> |
| 540 class RewriterBase : public MatchFinder::MatchCallback { | 572 class RewriterBase : public MatchFinder::MatchCallback { |
| 541 public: | 573 public: |
| 542 explicit RewriterBase(std::set<Replacement>* replacements) | 574 explicit RewriterBase(std::set<Replacement>* replacements) |
| 543 : replacements_(replacements) {} | 575 : replacements_(replacements) {} |
| 544 | 576 |
| 577 const TargetNode& GetTargetNode(const MatchFinder::MatchResult& result) { |
| 578 const TargetNode* target_node = result.Nodes.getNodeAs<TargetNode>( |
| 579 TargetNodeTraits<TargetNode>::GetName()); |
| 580 assert(target_node); |
| 581 return *target_node; |
| 582 } |
| 583 |
| 584 void AddReplacement(const MatchFinder::MatchResult& result, |
| 585 llvm::StringRef old_name, |
| 586 std::string new_name) { |
| 587 if (old_name == new_name) |
| 588 return; |
| 589 |
| 590 clang::SourceLocation loc = |
| 591 TargetNodeTraits<TargetNode>::GetLoc(GetTargetNode(result)); |
| 592 clang::CharSourceRange range = clang::CharSourceRange::getTokenRange(loc); |
| 593 replacements_->emplace(*result.SourceManager, range, new_name); |
| 594 replacement_names_.emplace(old_name.str(), std::move(new_name)); |
| 595 } |
| 596 |
| 597 const std::unordered_map<std::string, std::string>& replacement_names() |
| 598 const { |
| 599 return replacement_names_; |
| 600 } |
| 601 |
| 602 private: |
| 603 std::set<Replacement>* const replacements_; |
| 604 std::unordered_map<std::string, std::string> replacement_names_; |
| 605 }; |
| 606 |
| 607 template <typename DeclNode, typename TargetNode> |
| 608 class DeclRewriterBase : public RewriterBase<TargetNode> { |
| 609 public: |
| 610 using Base = RewriterBase<TargetNode>; |
| 611 |
| 612 explicit DeclRewriterBase(std::set<Replacement>* replacements) |
| 613 : Base(replacements) {} |
| 614 |
| 545 void run(const MatchFinder::MatchResult& result) override { | 615 void run(const MatchFinder::MatchResult& result) override { |
| 546 const DeclNode* decl = result.Nodes.getNodeAs<DeclNode>("decl"); | 616 const DeclNode* decl = result.Nodes.getNodeAs<DeclNode>("decl"); |
| 617 assert(decl); |
| 547 // If false, there's no name to be renamed. | 618 // If false, there's no name to be renamed. |
| 548 if (!decl->getIdentifier()) | 619 if (!decl->getIdentifier()) |
| 549 return; | 620 return; |
| 550 clang::SourceLocation decl_loc = | 621 clang::SourceLocation decl_loc = |
| 551 TargetNodeTraits<clang::NamedDecl>::GetLoc(*decl); | 622 TargetNodeTraits<clang::NamedDecl>::GetLoc(*decl); |
| 552 if (decl_loc.isMacroID()) { | 623 if (decl_loc.isMacroID()) { |
| 553 // Get the location of the spelling of the declaration. If token pasting | 624 // 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 | 625 // 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 | 626 // from there back to/ the actual macro with the foo##bar text. So just |
| 556 // don't replace in that case. | 627 // don't replace in that case. |
| 557 clang::SourceLocation spell = | 628 clang::SourceLocation spell = |
| 558 result.SourceManager->getSpellingLoc(decl_loc); | 629 result.SourceManager->getSpellingLoc(decl_loc); |
| 559 if (strcmp(result.SourceManager->getBufferName(spell), | 630 if (result.SourceManager->getBufferName(spell) == "<scratch space>") |
| 560 "<scratch space>") == 0) | |
| 561 return; | 631 return; |
| 562 } | 632 } |
| 563 clang::ASTContext* context = result.Context; | 633 clang::ASTContext* context = result.Context; |
| 564 std::string new_name; | 634 std::string new_name; |
| 565 if (!GetNameForDecl(*decl, *context, new_name)) | 635 if (!GetNameForDecl(*decl, *context, new_name)) |
| 566 return; // If false, the name was not suitable for renaming. | 636 return; // If false, the name was not suitable for renaming. |
| 567 llvm::StringRef old_name = decl->getName(); | 637 llvm::StringRef old_name = decl->getName(); |
| 568 if (old_name == new_name) | 638 Base::AddReplacement(result, old_name, std::move(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 } | 639 } |
| 640 }; |
| 577 | 641 |
| 578 const std::unordered_map<std::string, std::string>& replacement_names() | 642 using FieldDeclRewriter = DeclRewriterBase<clang::FieldDecl, clang::NamedDecl>; |
| 579 const { | 643 using VarDeclRewriter = DeclRewriterBase<clang::VarDecl, clang::NamedDecl>; |
| 580 return replacement_names_; | 644 using MemberRewriter = DeclRewriterBase<clang::FieldDecl, clang::MemberExpr>; |
| 645 using DeclRefRewriter = DeclRewriterBase<clang::VarDecl, clang::DeclRefExpr>; |
| 646 using FieldDeclRefRewriter = |
| 647 DeclRewriterBase<clang::FieldDecl, clang::DeclRefExpr>; |
| 648 using FunctionDeclRewriter = |
| 649 DeclRewriterBase<clang::FunctionDecl, clang::NamedDecl>; |
| 650 using FunctionRefRewriter = |
| 651 DeclRewriterBase<clang::FunctionDecl, clang::DeclRefExpr>; |
| 652 using ConstructorInitializerRewriter = |
| 653 DeclRewriterBase<clang::FieldDecl, clang::CXXCtorInitializer>; |
| 654 |
| 655 using MethodDeclRewriter = |
| 656 DeclRewriterBase<clang::CXXMethodDecl, clang::NamedDecl>; |
| 657 using MethodRefRewriter = |
| 658 DeclRewriterBase<clang::CXXMethodDecl, clang::DeclRefExpr>; |
| 659 using MethodMemberRewriter = |
| 660 DeclRewriterBase<clang::CXXMethodDecl, clang::MemberExpr>; |
| 661 |
| 662 using EnumConstantDeclRewriter = |
| 663 DeclRewriterBase<clang::EnumConstantDecl, clang::NamedDecl>; |
| 664 using EnumConstantDeclRefRewriter = |
| 665 DeclRewriterBase<clang::EnumConstantDecl, clang::DeclRefExpr>; |
| 666 |
| 667 using UnresolvedLookupRewriter = |
| 668 DeclRewriterBase<clang::NamedDecl, clang::UnresolvedLookupExpr>; |
| 669 using UnresolvedMemberRewriter = |
| 670 DeclRewriterBase<clang::NamedDecl, clang::UnresolvedMemberExpr>; |
| 671 |
| 672 using UsingDeclRewriter = DeclRewriterBase<clang::UsingDecl, clang::NamedDecl>; |
| 673 |
| 674 clang::DeclarationName GetUnresolvedName( |
| 675 const clang::UnresolvedMemberExpr& expr) { |
| 676 return expr.getMemberName(); |
| 677 } |
| 678 |
| 679 clang::DeclarationName GetUnresolvedName( |
| 680 const clang::UnresolvedUsingValueDecl& decl) { |
| 681 return decl.getDeclName(); |
| 682 } |
| 683 |
| 684 template <typename TargetNode> |
| 685 class UnresolvedRewriterBase : public RewriterBase<TargetNode> { |
| 686 public: |
| 687 using Base = RewriterBase<TargetNode>; |
| 688 |
| 689 explicit UnresolvedRewriterBase(std::set<Replacement>* replacements) |
| 690 : RewriterBase<TargetNode>(replacements) {} |
| 691 |
| 692 void run(const MatchFinder::MatchResult& result) override { |
| 693 const TargetNode& expr = Base::GetTargetNode(result); |
| 694 llvm::StringRef old_name = GetUnresolvedName(expr).getAsString(); |
| 695 std::string new_name; |
| 696 if (GuessNameForUnresolvedDependentNode(expr, *result.Context, old_name, |
| 697 new_name)) { |
| 698 Base::AddReplacement(result, old_name, std::move(new_name)); |
| 699 } |
| 581 } | 700 } |
| 582 | 701 |
| 583 private: | 702 private: |
| 584 std::set<Replacement>* const replacements_; | 703 // This method calculates a new name for nodes that depend on template |
| 585 std::unordered_map<std::string, std::string> replacement_names_; | 704 // parameters (http://en.cppreference.com/w/cpp/language/dependent_name). The |
| 705 // renaming is based on crude heuristics, because such nodes are not bound to |
| 706 // a specific decl until template instantiation - at the point of rename, one |
| 707 // cannot tell whether the node will eventually resolve to a field / method / |
| 708 // constant / etc. |
| 709 bool GuessNameForUnresolvedDependentNode(const TargetNode& node, |
| 710 clang::ASTContext& context, |
| 711 llvm::StringRef old_name, |
| 712 std::string& new_name) { |
| 713 // |m_fieldName| -> |field_name_|. |
| 714 if (old_name.startswith(kBlinkFieldPrefix)) { |
| 715 std::string field_name = old_name.str().substr(strlen(kBlinkFieldPrefix)); |
| 716 if (field_name.find('_') == std::string::npos) { |
| 717 new_name = CamelCaseToUnderscoreCase(field_name) + "_"; |
| 718 return true; |
| 719 } |
| 720 } |
| 721 |
| 722 // |T::myMethod(...)| -> |T::MyMethod(...)|. |
| 723 if ((old_name.find('_') == std::string::npos) && |
| 724 !IsBlacklistedFunctionOrMethodName(old_name)) { |
| 725 new_name = old_name; |
| 726 new_name[0] = clang::toUppercase(new_name[0]); |
| 727 return true; |
| 728 } |
| 729 |
| 730 // In the future we can consider more heuristics: |
| 731 // - "s_" and "g_" prefixes |
| 732 // - "ALL_CAPS" |
| 733 // - |T::myStaticField| -> |T::kMyStaticField| |
| 734 // (but have to be careful not to rename |value| in WTF/TypeTraits.h?) |
| 735 return false; |
| 736 } |
| 586 }; | 737 }; |
| 587 | 738 |
| 588 using FieldDeclRewriter = RewriterBase<clang::FieldDecl, clang::NamedDecl>; | 739 using UnresolvedDependentMemberRewriter = |
| 589 using VarDeclRewriter = RewriterBase<clang::VarDecl, clang::NamedDecl>; | 740 UnresolvedRewriterBase<clang::UnresolvedMemberExpr>; |
| 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 | 741 |
| 600 using MethodDeclRewriter = RewriterBase<clang::CXXMethodDecl, clang::NamedDecl>; | 742 using UnresolvedUsingValueDeclRewriter = |
| 601 using MethodRefRewriter = | 743 UnresolvedRewriterBase<clang::UnresolvedUsingValueDecl>; |
| 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 | 744 |
| 618 } // namespace | 745 } // namespace |
| 619 | 746 |
| 620 static llvm::cl::extrahelp common_help(CommonOptionsParser::HelpMessage); | 747 static llvm::cl::extrahelp common_help(CommonOptionsParser::HelpMessage); |
| 621 | 748 |
| 622 int main(int argc, const char* argv[]) { | 749 int main(int argc, const char* argv[]) { |
| 623 // TODO(dcheng): Clang tooling should do this itself. | 750 // TODO(dcheng): Clang tooling should do this itself. |
| 624 // http://llvm.org/bugs/show_bug.cgi?id=21627 | 751 // http://llvm.org/bugs/show_bug.cgi?id=21627 |
| 625 llvm::InitializeNativeTarget(); | 752 llvm::InitializeNativeTarget(); |
| 626 llvm::InitializeNativeTargetAsmParser(); | 753 llvm::InitializeNativeTargetAsmParser(); |
| (...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 878 // UnresolvedMemberExpr matcher below are analogous to how the | 1005 // UnresolvedMemberExpr matcher below are analogous to how the |
| 879 // rewriter has both a MemberRefRewriter matcher to rewrite | 1006 // rewriter has both a MemberRefRewriter matcher to rewrite |
| 880 // &T::method and a MethodMemberRewriter matcher to rewriter | 1007 // &T::method and a MethodMemberRewriter matcher to rewriter |
| 881 // t.method(). | 1008 // t.method(). |
| 882 allOverloadsMatch(anyOf(method_decl_matcher, | 1009 allOverloadsMatch(anyOf(method_decl_matcher, |
| 883 method_template_decl_matcher)))))); | 1010 method_template_decl_matcher)))))); |
| 884 UnresolvedLookupRewriter unresolved_lookup_rewriter(&replacements); | 1011 UnresolvedLookupRewriter unresolved_lookup_rewriter(&replacements); |
| 885 match_finder.addMatcher(unresolved_lookup_matcher, | 1012 match_finder.addMatcher(unresolved_lookup_matcher, |
| 886 &unresolved_lookup_rewriter); | 1013 &unresolved_lookup_rewriter); |
| 887 | 1014 |
| 888 // Unresolved member expressions ======== | 1015 // Unresolved member expressions (for non-dependent fields / methods) ======== |
| 889 // Similar to unresolved lookup expressions, but for methods in a member | 1016 // Similar to unresolved lookup expressions, but for methods in a member |
| 890 // context, e.g. var_with_templated_type.Method(). | 1017 // context, e.g. var_with_templated_type.Method(). |
| 891 auto unresolved_member_matcher = expr(id( | 1018 auto unresolved_member_matcher = expr(id( |
| 892 "expr", | 1019 "expr", |
| 893 unresolvedMemberExpr( | 1020 unresolvedMemberExpr( |
| 894 // Similar to UnresolvedLookupExprs, all the candidate methods must be | 1021 // Similar to UnresolvedLookupExprs, all the candidate methods must be |
| 895 // Blink methods/method templates. | 1022 // Blink methods/method templates. |
| 896 allOverloadsMatch( | 1023 allOverloadsMatch( |
| 897 anyOf(method_decl_matcher, method_template_decl_matcher))))); | 1024 anyOf(method_decl_matcher, method_template_decl_matcher))))); |
| 898 UnresolvedMemberRewriter unresolved_member_rewriter(&replacements); | 1025 UnresolvedMemberRewriter unresolved_member_rewriter(&replacements); |
| 899 match_finder.addMatcher(unresolved_member_matcher, | 1026 match_finder.addMatcher(unresolved_member_matcher, |
| 900 &unresolved_member_rewriter); | 1027 &unresolved_member_rewriter); |
| 901 | 1028 |
| 1029 // Unresolved using value decls ======== |
| 1030 // Example: |
| 1031 // template <typename T> |
| 1032 // class BaseClass { |
| 1033 // public: |
| 1034 // unsigned long m_size; |
| 1035 // }; |
| 1036 // template <typename T> |
| 1037 // class DerivedClass : protected BaseClass<T> { |
| 1038 // private: |
| 1039 // using Base = BaseClass<T>; |
| 1040 // using Base::m_size; // <- |m_size| here is matched by |
| 1041 // void method() { // |unresolved_using_value_decl_matcher|. |
| 1042 // m_size = 123; // <- |m_size| here is matched by |
| 1043 // } // |unresolved_dependent_using_matcher|. |
| 1044 // }; |
| 1045 auto unresolved_dependent_using_matcher = |
| 1046 expr(id("expr", unresolvedMemberExpr(allOverloadsMatch(allOf( |
| 1047 in_blink_namespace, unresolvedUsingValueDecl()))))); |
| 1048 UnresolvedDependentMemberRewriter unresolved_dependent_member_rewriter( |
| 1049 &replacements); |
| 1050 match_finder.addMatcher(unresolved_dependent_using_matcher, |
| 1051 &unresolved_dependent_member_rewriter); |
| 1052 auto unresolved_using_value_decl_matcher = |
| 1053 decl(id("decl", unresolvedUsingValueDecl(in_blink_namespace))); |
| 1054 UnresolvedUsingValueDeclRewriter unresolved_using_value_decl_rewriter( |
| 1055 &replacements); |
| 1056 match_finder.addMatcher(unresolved_using_value_decl_matcher, |
| 1057 &unresolved_using_value_decl_rewriter); |
| 1058 |
| 902 // Using declarations ======== | 1059 // Using declarations ======== |
| 903 // Given | 1060 // Given |
| 904 // using blink::X; | 1061 // using blink::X; |
| 905 // matches |using blink::X|. | 1062 // matches |using blink::X|. |
| 906 auto using_decl_matcher = id( | 1063 auto using_decl_matcher = id( |
| 907 "decl", usingDecl(hasAnyUsingShadowDecl(hasTargetDecl(anyOf( | 1064 "decl", usingDecl(hasAnyUsingShadowDecl(hasTargetDecl(anyOf( |
| 908 var_decl_matcher, field_decl_matcher, function_decl_matcher, | 1065 var_decl_matcher, field_decl_matcher, function_decl_matcher, |
| 909 method_decl_matcher, function_template_decl_matcher, | 1066 method_decl_matcher, function_template_decl_matcher, |
| 910 method_template_decl_matcher, enum_member_decl_matcher))))); | 1067 method_template_decl_matcher, enum_member_decl_matcher))))); |
| 911 UsingDeclRewriter using_decl_rewriter(&replacements); | 1068 UsingDeclRewriter using_decl_rewriter(&replacements); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 955 for (const auto& r : replacements) { | 1112 for (const auto& r : replacements) { |
| 956 std::string replacement_text = r.getReplacementText().str(); | 1113 std::string replacement_text = r.getReplacementText().str(); |
| 957 std::replace(replacement_text.begin(), replacement_text.end(), '\n', '\0'); | 1114 std::replace(replacement_text.begin(), replacement_text.end(), '\n', '\0'); |
| 958 llvm::outs() << "r:::" << r.getFilePath() << ":::" << r.getOffset() | 1115 llvm::outs() << "r:::" << r.getFilePath() << ":::" << r.getOffset() |
| 959 << ":::" << r.getLength() << ":::" << replacement_text << "\n"; | 1116 << ":::" << r.getLength() << ":::" << replacement_text << "\n"; |
| 960 } | 1117 } |
| 961 llvm::outs() << "==== END EDITS ====\n"; | 1118 llvm::outs() << "==== END EDITS ====\n"; |
| 962 | 1119 |
| 963 return 0; | 1120 return 0; |
| 964 } | 1121 } |
| OLD | NEW |