Chromium Code Reviews| 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 662 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 673 explicit RewriterBase(std::set<Replacement>* replacements) | 673 explicit RewriterBase(std::set<Replacement>* replacements) |
| 674 : replacements_(replacements) {} | 674 : replacements_(replacements) {} |
| 675 | 675 |
| 676 const TargetNode& GetTargetNode(const MatchFinder::MatchResult& result) { | 676 const TargetNode& GetTargetNode(const MatchFinder::MatchResult& result) { |
| 677 const TargetNode* target_node = result.Nodes.getNodeAs<TargetNode>( | 677 const TargetNode* target_node = result.Nodes.getNodeAs<TargetNode>( |
| 678 TargetNodeTraits<TargetNode>::GetName()); | 678 TargetNodeTraits<TargetNode>::GetName()); |
| 679 assert(target_node); | 679 assert(target_node); |
| 680 return *target_node; | 680 return *target_node; |
| 681 } | 681 } |
| 682 | 682 |
| 683 bool GenerateReplacement(const MatchFinder::MatchResult& result, | |
| 684 clang::SourceLocation loc, | |
| 685 llvm::StringRef old_name, | |
| 686 std::string new_name, | |
| 687 Replacement* replacement) { | |
| 688 const clang::ASTContext& context = *result.Context; | |
| 689 const clang::SourceManager& source_manager = *result.SourceManager; | |
| 690 | |
| 691 if (loc.isMacroID()) { | |
| 692 // Try to jump "above" the scratch buffer if |loc| is inside | |
| 693 // token##Concatenation. | |
| 694 const int kMaxJumps = 5; | |
| 695 bool verified_out_of_scratch_space = false; | |
| 696 for (int i = 0; i < kMaxJumps && !verified_out_of_scratch_space; i++) { | |
| 697 clang::SourceLocation spell = source_manager.getSpellingLoc(loc); | |
| 698 verified_out_of_scratch_space = | |
| 699 source_manager.getBufferName(spell) != "<scratch space>"; | |
| 700 if (!verified_out_of_scratch_space) | |
| 701 loc = source_manager.getImmediateMacroCallerLoc(loc); | |
| 702 } | |
| 703 if (!verified_out_of_scratch_space) | |
| 704 return false; | |
| 705 } | |
| 706 | |
| 707 // If the edit affects only the first character of the identifier, then | |
| 708 // narrow down the edit to only this single character. This is important | |
| 709 // for dealing with toFooBar -> ToFooBar method renaming when the method | |
| 710 // name is built using macro token concatenation like to##macroArgument - in | |
| 711 // this case we should only rewrite "t" -> "T" and leave "o##macroArgument" | |
| 712 // untouched. | |
| 713 llvm::StringRef expected_old_text = old_name; | |
| 714 llvm::StringRef new_text = new_name; | |
| 715 if (loc.isMacroID() && expected_old_text.substr(1) == new_text.substr(1)) { | |
| 716 expected_old_text = expected_old_text.substr(0, 1); | |
| 717 new_text = new_text.substr(0, 1); | |
| 718 } | |
| 719 clang::SourceLocation spell = source_manager.getSpellingLoc(loc); | |
| 720 clang::CharSourceRange range = clang::CharSourceRange::getCharRange( | |
| 721 spell, spell.getLocWithOffset(expected_old_text.size())); | |
| 722 | |
| 723 // We need to ensure that |actual_old_text| is the same as | |
| 724 // |expected_old_text| - it can be different if |actual_old_text| contains | |
| 725 // a macro argument (see DEFINE_WITH_TOKEN_CONCATENATION2 in | |
| 726 // macros-original.cc testcase). | |
| 727 StringRef actual_old_text = clang::Lexer::getSourceText( | |
| 728 range, source_manager, context.getLangOpts()); | |
| 729 if (actual_old_text != expected_old_text) | |
| 730 return false; | |
| 731 | |
| 732 if (replacement) | |
| 733 *replacement = Replacement(source_manager, range, new_text); | |
| 734 return true; | |
| 735 } | |
| 736 | |
| 683 void AddReplacement(const MatchFinder::MatchResult& result, | 737 void AddReplacement(const MatchFinder::MatchResult& result, |
| 684 llvm::StringRef old_name, | 738 llvm::StringRef old_name, |
| 685 std::string new_name) { | 739 std::string new_name) { |
| 686 if (old_name == new_name) | 740 if (old_name == new_name) |
| 687 return; | 741 return; |
| 688 | 742 |
| 689 clang::SourceLocation loc = | 743 clang::SourceLocation loc = |
| 690 TargetNodeTraits<TargetNode>::GetLoc(GetTargetNode(result)); | 744 TargetNodeTraits<TargetNode>::GetLoc(GetTargetNode(result)); |
| 745 | |
| 746 Replacement replacement; | |
| 747 if (!GenerateReplacement(result, loc, old_name, new_name, &replacement)) | |
| 748 return; | |
| 749 | |
| 750 replacements_->insert(std::move(replacement)); | |
| 691 edit_tracker_.Add(*result.SourceManager, loc, old_name, new_name); | 751 edit_tracker_.Add(*result.SourceManager, loc, old_name, new_name); |
| 692 | |
| 693 clang::CharSourceRange range = clang::CharSourceRange::getTokenRange(loc); | |
| 694 replacements_->emplace(*result.SourceManager, range, new_name); | |
| 695 } | 752 } |
| 696 | 753 |
| 697 const EditTracker& edit_tracker() const { return edit_tracker_; } | 754 const EditTracker& edit_tracker() const { return edit_tracker_; } |
| 698 | 755 |
| 699 private: | 756 private: |
| 700 std::set<Replacement>* const replacements_; | 757 std::set<Replacement>* const replacements_; |
| 701 EditTracker edit_tracker_; | 758 EditTracker edit_tracker_; |
| 702 }; | 759 }; |
| 703 | 760 |
| 704 template <typename DeclNode, typename TargetNode> | 761 template <typename DeclNode, typename TargetNode> |
| 705 class DeclRewriterBase : public RewriterBase<TargetNode> { | 762 class DeclRewriterBase : public RewriterBase<TargetNode> { |
| 706 public: | 763 public: |
| 707 using Base = RewriterBase<TargetNode>; | 764 using Base = RewriterBase<TargetNode>; |
| 708 | 765 |
| 709 explicit DeclRewriterBase(std::set<Replacement>* replacements) | 766 explicit DeclRewriterBase(std::set<Replacement>* replacements) |
| 710 : Base(replacements) {} | 767 : Base(replacements) {} |
| 711 | 768 |
| 712 void run(const MatchFinder::MatchResult& result) override { | 769 void run(const MatchFinder::MatchResult& result) override { |
| 713 const DeclNode* decl = result.Nodes.getNodeAs<DeclNode>("decl"); | 770 const DeclNode* decl = result.Nodes.getNodeAs<DeclNode>("decl"); |
| 714 assert(decl); | 771 assert(decl); |
| 715 // If false, there's no name to be renamed. | 772 llvm::StringRef old_name = decl->getName(); |
| 773 | |
| 774 // Return early if there's no name to be renamed. | |
| 716 if (!decl->getIdentifier()) | 775 if (!decl->getIdentifier()) |
| 717 return; | 776 return; |
| 777 | |
| 778 // Get the new name. | |
| 779 std::string new_name; | |
| 780 if (!GetNameForDecl(*decl, *result.Context, new_name)) | |
| 781 return; // If false, the name was not suitable for renaming. | |
| 782 | |
| 783 // Check if we are able to rewrite the decl (to avoid rewriting if the | |
| 784 // decl's identifier is part of macro##Token##Concatenation). | |
| 718 clang::SourceLocation decl_loc = | 785 clang::SourceLocation decl_loc = |
| 719 TargetNodeTraits<clang::NamedDecl>::GetLoc(*decl); | 786 TargetNodeTraits<clang::NamedDecl>::GetLoc(*decl); |
| 720 if (decl_loc.isMacroID()) { | 787 if (!Base::GenerateReplacement(result, decl_loc, old_name, new_name, |
| 721 // Get the location of the spelling of the declaration. If token pasting | 788 nullptr)) |
|
dcheng
2016/12/23 00:35:26
It seems a bit odd to call this twice; can we avoi
Łukasz Anforowicz
2016/12/27 19:17:23
First observation is that the call here is for |de
| |
| 722 // was used this will be in "scratch space" and we don't know how to get | 789 return; |
| 723 // from there back to/ the actual macro with the foo##bar text. So just | 790 |
| 724 // don't replace in that case. | |
| 725 clang::SourceLocation spell = | |
| 726 result.SourceManager->getSpellingLoc(decl_loc); | |
| 727 if (result.SourceManager->getBufferName(spell) == "<scratch space>") | |
| 728 return; | |
| 729 } | |
| 730 clang::ASTContext* context = result.Context; | |
| 731 std::string new_name; | |
| 732 if (!GetNameForDecl(*decl, *context, new_name)) | |
| 733 return; // If false, the name was not suitable for renaming. | |
| 734 llvm::StringRef old_name = decl->getName(); | |
| 735 Base::AddReplacement(result, old_name, std::move(new_name)); | 791 Base::AddReplacement(result, old_name, std::move(new_name)); |
| 736 } | 792 } |
| 737 }; | 793 }; |
| 738 | 794 |
| 739 using FieldDeclRewriter = DeclRewriterBase<clang::FieldDecl, clang::NamedDecl>; | 795 using FieldDeclRewriter = DeclRewriterBase<clang::FieldDecl, clang::NamedDecl>; |
| 740 using VarDeclRewriter = DeclRewriterBase<clang::VarDecl, clang::NamedDecl>; | 796 using VarDeclRewriter = DeclRewriterBase<clang::VarDecl, clang::NamedDecl>; |
| 741 using MemberRewriter = DeclRewriterBase<clang::FieldDecl, clang::MemberExpr>; | 797 using MemberRewriter = DeclRewriterBase<clang::FieldDecl, clang::MemberExpr>; |
| 742 using DeclRefRewriter = DeclRewriterBase<clang::VarDecl, clang::DeclRefExpr>; | 798 using DeclRefRewriter = DeclRewriterBase<clang::VarDecl, clang::DeclRefExpr>; |
| 743 using FieldDeclRefRewriter = | 799 using FieldDeclRefRewriter = |
| 744 DeclRewriterBase<clang::FieldDecl, clang::DeclRefExpr>; | 800 DeclRewriterBase<clang::FieldDecl, clang::DeclRefExpr>; |
| (...skipping 549 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1294 for (const auto& r : replacements) { | 1350 for (const auto& r : replacements) { |
| 1295 std::string replacement_text = r.getReplacementText().str(); | 1351 std::string replacement_text = r.getReplacementText().str(); |
| 1296 std::replace(replacement_text.begin(), replacement_text.end(), '\n', '\0'); | 1352 std::replace(replacement_text.begin(), replacement_text.end(), '\n', '\0'); |
| 1297 llvm::outs() << "r:::" << r.getFilePath() << ":::" << r.getOffset() | 1353 llvm::outs() << "r:::" << r.getFilePath() << ":::" << r.getOffset() |
| 1298 << ":::" << r.getLength() << ":::" << replacement_text << "\n"; | 1354 << ":::" << r.getLength() << ":::" << replacement_text << "\n"; |
| 1299 } | 1355 } |
| 1300 llvm::outs() << "==== END EDITS ====\n"; | 1356 llvm::outs() << "==== END EDITS ====\n"; |
| 1301 | 1357 |
| 1302 return 0; | 1358 return 0; |
| 1303 } | 1359 } |
| OLD | NEW |