Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(904)

Side by Side Diff: tools/clang/rewrite_to_chrome_style/RewriteToChromeStyle.cpp

Issue 2592273002: Support rewriting |to##macroArg()| into |To##macroArg()|. (Closed)
Patch Set: Don't minimize the edit if not editing a macro. Created 3 years, 12 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | tools/clang/rewrite_to_chrome_style/tests/macros-expected.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | tools/clang/rewrite_to_chrome_style/tests/macros-expected.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698