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

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

Issue 2609473002: Renaming blink method names inside gmock's EXPECT_CALL macro invocation. (Closed)
Patch Set: Using PPCallbacks::RecordExpectCallMacroInvocation. Created 3 years, 11 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
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:
11 // const int maxThings => const int kMaxThings 11 // const int maxThings => const int kMaxThings
12 // free functions and methods: 12 // free functions and methods:
13 // void doThisThenThat() => void DoThisAndThat() 13 // void doThisThenThat() => void DoThisAndThat()
14 14
15 #include <assert.h> 15 #include <assert.h>
16 #include <algorithm> 16 #include <algorithm>
17 #include <memory> 17 #include <memory>
18 #include <set> 18 #include <set>
19 #include <string> 19 #include <string>
20 20
21 #include "clang/AST/ASTContext.h" 21 #include "clang/AST/ASTContext.h"
22 #include "clang/ASTMatchers/ASTMatchFinder.h" 22 #include "clang/ASTMatchers/ASTMatchFinder.h"
23 #include "clang/ASTMatchers/ASTMatchers.h" 23 #include "clang/ASTMatchers/ASTMatchers.h"
24 #include "clang/ASTMatchers/ASTMatchersMacros.h" 24 #include "clang/ASTMatchers/ASTMatchersMacros.h"
25 #include "clang/Basic/CharInfo.h" 25 #include "clang/Basic/CharInfo.h"
26 #include "clang/Basic/SourceManager.h" 26 #include "clang/Basic/SourceManager.h"
27 #include "clang/Frontend/CompilerInstance.h"
27 #include "clang/Frontend/FrontendActions.h" 28 #include "clang/Frontend/FrontendActions.h"
29 #include "clang/Lex/MacroArgs.h"
28 #include "clang/Lex/Lexer.h" 30 #include "clang/Lex/Lexer.h"
31 #include "clang/Lex/PPCallbacks.h"
32 #include "clang/Lex/Preprocessor.h"
29 #include "clang/Tooling/CommonOptionsParser.h" 33 #include "clang/Tooling/CommonOptionsParser.h"
30 #include "clang/Tooling/Refactoring.h" 34 #include "clang/Tooling/Refactoring.h"
31 #include "clang/Tooling/Tooling.h" 35 #include "clang/Tooling/Tooling.h"
32 #include "llvm/Support/CommandLine.h" 36 #include "llvm/Support/CommandLine.h"
33 #include "llvm/Support/TargetSelect.h" 37 #include "llvm/Support/TargetSelect.h"
34 38
35 #include "EditTracker.h" 39 #include "EditTracker.h"
36 40
37 using namespace clang::ast_matchers; 41 using namespace clang::ast_matchers;
38 using clang::tooling::CommonOptionsParser; 42 using clang::tooling::CommonOptionsParser;
39 using clang::tooling::Replacement; 43 using clang::tooling::Replacement;
40 using llvm::StringRef; 44 using llvm::StringRef;
41 45
42 namespace { 46 namespace {
43 47
44 const char kBlinkFieldPrefix[] = "m_"; 48 const char kBlinkFieldPrefix[] = "m_";
45 const char kBlinkStaticMemberPrefix[] = "s_"; 49 const char kBlinkStaticMemberPrefix[] = "s_";
46 const char kGeneratedFileRegex[] = "^gen/|/gen/"; 50 const char kGeneratedFileRegex[] = "^gen/|/gen/";
51 const char kGMockMethodNamePrefix[] = "gmock_";
47 52
48 template <typename MatcherType, typename NodeType> 53 template <typename MatcherType, typename NodeType>
49 bool IsMatching(const MatcherType& matcher, 54 bool IsMatching(const MatcherType& matcher,
50 const NodeType& node, 55 const NodeType& node,
51 clang::ASTContext& context) { 56 clang::ASTContext& context) {
52 return !match(matcher, node, context).empty(); 57 return !match(matcher, node, context).empty();
53 } 58 }
54 59
55 const clang::ast_matchers::internal:: 60 const clang::ast_matchers::internal::
56 VariadicDynCastAllOfMatcher<clang::Expr, clang::UnresolvedMemberExpr> 61 VariadicDynCastAllOfMatcher<clang::Expr, clang::UnresolvedMemberExpr>
(...skipping 15 matching lines...) Expand all
72 return Node.isInstance(); 77 return Node.isInstance();
73 } 78 }
74 79
75 AST_MATCHER_P(clang::FunctionTemplateDecl, 80 AST_MATCHER_P(clang::FunctionTemplateDecl,
76 templatedDecl, 81 templatedDecl,
77 clang::ast_matchers::internal::Matcher<clang::FunctionDecl>, 82 clang::ast_matchers::internal::Matcher<clang::FunctionDecl>,
78 InnerMatcher) { 83 InnerMatcher) {
79 return InnerMatcher.matches(*Node.getTemplatedDecl(), Finder, Builder); 84 return InnerMatcher.matches(*Node.getTemplatedDecl(), Finder, Builder);
80 } 85 }
81 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).
91 AST_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
82 // If |InnerMatcher| matches |top|, then the returned matcher will match: 122 // If |InnerMatcher| matches |top|, then the returned matcher will match:
83 // - |top::function| 123 // - |top::function|
84 // - |top::Class::method| 124 // - |top::Class::method|
85 // - |top::internal::Class::method| 125 // - |top::internal::Class::method|
86 AST_MATCHER_P( 126 AST_MATCHER_P(
87 clang::NestedNameSpecifier, 127 clang::NestedNameSpecifier,
88 hasTopLevelPrefix, 128 hasTopLevelPrefix,
89 clang::ast_matchers::internal::Matcher<clang::NestedNameSpecifier>, 129 clang::ast_matchers::internal::Matcher<clang::NestedNameSpecifier>,
90 InnerMatcher) { 130 InnerMatcher) {
91 const clang::NestedNameSpecifier* NodeToMatch = &Node; 131 const clang::NestedNameSpecifier* NodeToMatch = &Node;
(...skipping 627 matching lines...) Expand 10 before | Expand all | Expand 10 after
719 template <> 759 template <>
720 struct TargetNodeTraits<clang::UnresolvedUsingValueDecl> { 760 struct TargetNodeTraits<clang::UnresolvedUsingValueDecl> {
721 static clang::SourceLocation GetLoc( 761 static clang::SourceLocation GetLoc(
722 const clang::UnresolvedUsingValueDecl& decl) { 762 const clang::UnresolvedUsingValueDecl& decl) {
723 return decl.getNameInfo().getLoc(); 763 return decl.getNameInfo().getLoc();
724 } 764 }
725 static const char* GetName() { return "decl"; } 765 static const char* GetName() { return "decl"; }
726 static const char* GetType() { return "UnresolvedUsingValueDecl"; } 766 static const char* GetType() { return "UnresolvedUsingValueDecl"; }
727 }; 767 };
728 768
769 bool JumpAboveMacroScratchSpace(const clang::SourceManager& source_manager,
770 clang::SourceLocation* loc) {
771 if (loc->isMacroID()) {
772 // Try to jump "above" the scratch buffer if |loc| is inside
773 // token##Concatenation.
774 const int kMaxJumps = 5;
775 bool verified_out_of_scratch_space = false;
776 for (int i = 0; i < kMaxJumps && !verified_out_of_scratch_space; i++) {
777 clang::SourceLocation spell = source_manager.getSpellingLoc(*loc);
778 verified_out_of_scratch_space =
779 source_manager.getBufferName(spell) != "<scratch space>";
780 if (!verified_out_of_scratch_space)
781 *loc = source_manager.getImmediateMacroCallerLoc(*loc);
782 }
783 if (!verified_out_of_scratch_space)
784 return false;
785 }
786
787 return true;
788 }
789
729 template <typename TargetNode> 790 template <typename TargetNode>
730 class RewriterBase : public MatchFinder::MatchCallback { 791 class RewriterBase : public MatchFinder::MatchCallback {
731 public: 792 public:
732 explicit RewriterBase(std::set<Replacement>* replacements) 793 explicit RewriterBase(std::set<Replacement>* replacements)
733 : replacements_(replacements) {} 794 : replacements_(replacements) {}
734 795
735 const TargetNode& GetTargetNode(const MatchFinder::MatchResult& result) { 796 const TargetNode& GetTargetNode(const MatchFinder::MatchResult& result) {
736 const TargetNode* target_node = result.Nodes.getNodeAs<TargetNode>( 797 const TargetNode* target_node = result.Nodes.getNodeAs<TargetNode>(
737 TargetNodeTraits<TargetNode>::GetName()); 798 TargetNodeTraits<TargetNode>::GetName());
738 assert(target_node); 799 assert(target_node);
739 return *target_node; 800 return *target_node;
740 } 801 }
741 802
742 bool GenerateReplacement(const MatchFinder::MatchResult& result, 803 bool GenerateReplacement(const MatchFinder::MatchResult& result,
743 clang::SourceLocation loc, 804 clang::SourceLocation loc,
744 llvm::StringRef old_name, 805 llvm::StringRef old_name,
745 std::string new_name, 806 std::string new_name,
746 Replacement* replacement) { 807 Replacement* replacement) {
747 const clang::ASTContext& context = *result.Context; 808 const clang::ASTContext& context = *result.Context;
748 const clang::SourceManager& source_manager = *result.SourceManager; 809 const clang::SourceManager& source_manager = *result.SourceManager;
749 810
750 if (loc.isMacroID()) { 811 if (!JumpAboveMacroScratchSpace(source_manager, &loc))
751 // Try to jump "above" the scratch buffer if |loc| is inside 812 return false;
752 // token##Concatenation.
753 const int kMaxJumps = 5;
754 bool verified_out_of_scratch_space = false;
755 for (int i = 0; i < kMaxJumps && !verified_out_of_scratch_space; i++) {
756 clang::SourceLocation spell = source_manager.getSpellingLoc(loc);
757 verified_out_of_scratch_space =
758 source_manager.getBufferName(spell) != "<scratch space>";
759 if (!verified_out_of_scratch_space)
760 loc = source_manager.getImmediateMacroCallerLoc(loc);
761 }
762 if (!verified_out_of_scratch_space)
763 return false;
764 }
765 813
766 // If the edit affects only the first character of the identifier, then 814 // If the edit affects only the first character of the identifier, then
767 // narrow down the edit to only this single character. This is important 815 // narrow down the edit to only this single character. This is important
768 // for dealing with toFooBar -> ToFooBar method renaming when the method 816 // for dealing with toFooBar -> ToFooBar method renaming when the method
769 // name is built using macro token concatenation like to##macroArgument - in 817 // name is built using macro token concatenation like to##macroArgument - in
770 // this case we should only rewrite "t" -> "T" and leave "o##macroArgument" 818 // this case we should only rewrite "t" -> "T" and leave "o##macroArgument"
771 // untouched. 819 // untouched.
772 llvm::StringRef expected_old_text = old_name; 820 llvm::StringRef expected_old_text = old_name;
773 llvm::StringRef new_text = new_name; 821 llvm::StringRef new_text = new_name;
774 if (loc.isMacroID() && expected_old_text.substr(1) == new_text.substr(1)) { 822 if (loc.isMacroID() && expected_old_text.substr(1) == new_text.substr(1)) {
(...skipping 11 matching lines...) Expand all
786 StringRef actual_old_text = clang::Lexer::getSourceText( 834 StringRef actual_old_text = clang::Lexer::getSourceText(
787 range, source_manager, context.getLangOpts()); 835 range, source_manager, context.getLangOpts());
788 if (actual_old_text != expected_old_text) 836 if (actual_old_text != expected_old_text)
789 return false; 837 return false;
790 838
791 if (replacement) 839 if (replacement)
792 *replacement = Replacement(source_manager, range, new_text); 840 *replacement = Replacement(source_manager, range, new_text);
793 return true; 841 return true;
794 } 842 }
795 843
844 virtual clang::SourceLocation GetTargetLoc(
845 const MatchFinder::MatchResult& result) {
846 return TargetNodeTraits<TargetNode>::GetLoc(GetTargetNode(result));
847 }
848
796 void AddReplacement(const MatchFinder::MatchResult& result, 849 void AddReplacement(const MatchFinder::MatchResult& result,
797 llvm::StringRef old_name, 850 llvm::StringRef old_name,
798 std::string new_name) { 851 std::string new_name) {
799 if (old_name == new_name) 852 if (old_name == new_name)
800 return; 853 return;
801 854
802 clang::SourceLocation loc = 855 clang::SourceLocation loc = GetTargetLoc(result);
803 TargetNodeTraits<TargetNode>::GetLoc(GetTargetNode(result)); 856 if (loc.isInvalid())
857 return;
804 858
805 Replacement replacement; 859 Replacement replacement;
806 if (!GenerateReplacement(result, loc, old_name, new_name, &replacement)) 860 if (!GenerateReplacement(result, loc, old_name, new_name, &replacement))
807 return; 861 return;
808 862
809 replacements_->insert(std::move(replacement)); 863 replacements_->insert(std::move(replacement));
810 edit_tracker_.Add(*result.SourceManager, loc, old_name, new_name); 864 edit_tracker_.Add(*result.SourceManager, loc, old_name, new_name);
811 } 865 }
812 866
813 const EditTracker& edit_tracker() const { return edit_tracker_; } 867 const EditTracker& edit_tracker() const { return edit_tracker_; }
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
876 using EnumConstantDeclRefRewriter = 930 using EnumConstantDeclRefRewriter =
877 DeclRewriterBase<clang::EnumConstantDecl, clang::DeclRefExpr>; 931 DeclRewriterBase<clang::EnumConstantDecl, clang::DeclRefExpr>;
878 932
879 using UnresolvedLookupRewriter = 933 using UnresolvedLookupRewriter =
880 DeclRewriterBase<clang::NamedDecl, clang::UnresolvedLookupExpr>; 934 DeclRewriterBase<clang::NamedDecl, clang::UnresolvedLookupExpr>;
881 using UnresolvedMemberRewriter = 935 using UnresolvedMemberRewriter =
882 DeclRewriterBase<clang::NamedDecl, clang::UnresolvedMemberExpr>; 936 DeclRewriterBase<clang::NamedDecl, clang::UnresolvedMemberExpr>;
883 937
884 using UsingDeclRewriter = DeclRewriterBase<clang::UsingDecl, clang::NamedDecl>; 938 using UsingDeclRewriter = DeclRewriterBase<clang::UsingDecl, clang::NamedDecl>;
885 939
940 class GMockMemberRewriter
941 : public DeclRewriterBase<clang::CXXMethodDecl, clang::MemberExpr> {
942 public:
943 using Base = DeclRewriterBase<clang::CXXMethodDecl, clang::MemberExpr>;
944
945 explicit GMockMemberRewriter(std::set<Replacement>* replacements)
946 : Base(replacements) {}
947
948 std::unique_ptr<clang::PPCallbacks> CreatePreprocessorCallbacks() {
949 return llvm::make_unique<GMockMemberRewriter::PPCallbacks>(this);
950 }
951
952 clang::SourceLocation GetTargetLoc(
953 const MatchFinder::MatchResult& result) override {
954 // Find location of the gmock_##MockedMethod identifier.
955 clang::SourceLocation target_loc = Base::GetTargetLoc(result);
956
957 // Find location of EXPECT_CALL macro invocation.
958 clang::SourceLocation macro_call_loc = target_loc;
959 if (!JumpAboveMacroScratchSpace(*result.SourceManager, &macro_call_loc))
960 return clang::SourceLocation();
961 macro_call_loc = result.SourceManager->getExpansionLoc(macro_call_loc);
962
963 // Map |macro_call_loc| to argument location (location of the method name).
964 auto it = expect_call_to_2nd_arg.find(macro_call_loc);
965 if (it == expect_call_to_2nd_arg.end())
966 return clang::SourceLocation();
967 return it->second;
968 }
969
970 private:
971 std::map<clang::SourceLocation, clang::SourceLocation> expect_call_to_2nd_arg;
972
973 // Called from PPCallbacks with the locations of EXPECT_CALL macro invocation:
974 // Example:
975 // EXPECT_CALL(my_mock, myMethod(123, 456));
976 // ^- expansion_loc ^- actual_arg_loc
977 void RecordExpectCallMacroInvocation(clang::SourceLocation expansion_loc,
978 clang::SourceLocation second_arg_loc) {
979 expect_call_to_2nd_arg[expansion_loc] = second_arg_loc;
980 }
981
982 class PPCallbacks : public clang::PPCallbacks {
983 public:
984 PPCallbacks(GMockMemberRewriter* rewriter) : rewriter_(rewriter) {}
985 ~PPCallbacks() override {}
986 void MacroExpands(const clang::Token& name,
987 const clang::MacroDefinition& def,
988 clang::SourceRange range,
989 const clang::MacroArgs* args) override {
990 clang::IdentifierInfo* id = name.getIdentifierInfo();
991 if (!id)
992 return;
993
994 if (id->getName() != "EXPECT_CALL")
995 return;
996
997 if (def.getMacroInfo()->getNumArgs() != 2)
998 return;
999
1000 // TODO(lukasza): Should check if def.getMacroInfo()->getDefinitionLoc()
1001 // is in testing/gmock/include/gmock/gmock-spec-builders.h but I don't
1002 // know how to get clang::SourceManager to call getFileName.
Łukasz Anforowicz 2017/01/07 01:16:29 This inaccuracy is probably okay - even if there a
1003
1004 rewriter_->RecordExpectCallMacroInvocation(
1005 name.getLocation(), args->getUnexpArgument(1)->getLocation());
1006 }
1007
1008 private:
1009 GMockMemberRewriter* rewriter_;
1010 };
1011 };
1012
886 clang::DeclarationName GetUnresolvedName( 1013 clang::DeclarationName GetUnresolvedName(
887 const clang::UnresolvedMemberExpr& expr) { 1014 const clang::UnresolvedMemberExpr& expr) {
888 return expr.getMemberName(); 1015 return expr.getMemberName();
889 } 1016 }
890 1017
891 clang::DeclarationName GetUnresolvedName( 1018 clang::DeclarationName GetUnresolvedName(
892 const clang::DependentScopeDeclRefExpr& expr) { 1019 const clang::DependentScopeDeclRefExpr& expr) {
893 return expr.getDeclName(); 1020 return expr.getDeclName();
894 } 1021 }
895 1022
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
1013 1140
1014 using UnresolvedUsingValueDeclRewriter = 1141 using UnresolvedUsingValueDeclRewriter =
1015 UnresolvedRewriterBase<clang::UnresolvedUsingValueDecl>; 1142 UnresolvedRewriterBase<clang::UnresolvedUsingValueDecl>;
1016 1143
1017 using DependentScopeDeclRefExprRewriter = 1144 using DependentScopeDeclRefExprRewriter =
1018 UnresolvedRewriterBase<clang::DependentScopeDeclRefExpr>; 1145 UnresolvedRewriterBase<clang::DependentScopeDeclRefExpr>;
1019 1146
1020 using CXXDependentScopeMemberExprRewriter = 1147 using CXXDependentScopeMemberExprRewriter =
1021 UnresolvedRewriterBase<clang::CXXDependentScopeMemberExpr>; 1148 UnresolvedRewriterBase<clang::CXXDependentScopeMemberExpr>;
1022 1149
1150 class SourceFileCallbacks : public clang::tooling::SourceFileCallbacks {
1151 public:
1152 SourceFileCallbacks() : source_counter_(0) {}
1153 ~SourceFileCallbacks() override {}
1154
1155 void AddPPCallbacks(std::unique_ptr<clang::PPCallbacks> new_callbacks) {
1156 if (!pp_callbacks_) {
1157 pp_callbacks_ = std::move(new_callbacks);
1158 } else {
1159 pp_callbacks_ = llvm::make_unique<clang::PPChainedCallbacks>(
1160 std::move(new_callbacks), std::move(pp_callbacks_));
1161 }
1162 }
1163
1164 // clang::tooling::SourceFileCallbacks override:
1165 bool handleBeginSource(clang::CompilerInstance& compiler,
1166 llvm::StringRef Filename) override {
1167 source_counter_++;
1168 assert(source_counter_ == 1); // We only have *one* pp_callbacks_.
1169
1170 compiler.getPreprocessor().addPPCallbacks(std::move(pp_callbacks_));
1171 return true;
1172 }
1173
1174 private:
1175 int source_counter_;
1176 std::unique_ptr<clang::PPCallbacks> pp_callbacks_;
1177 };
1178
1023 } // namespace 1179 } // namespace
1024 1180
1025 static llvm::cl::extrahelp common_help(CommonOptionsParser::HelpMessage); 1181 static llvm::cl::extrahelp common_help(CommonOptionsParser::HelpMessage);
1026 1182
1027 int main(int argc, const char* argv[]) { 1183 int main(int argc, const char* argv[]) {
1028 // TODO(dcheng): Clang tooling should do this itself. 1184 // TODO(dcheng): Clang tooling should do this itself.
1029 // http://llvm.org/bugs/show_bug.cgi?id=21627 1185 // http://llvm.org/bugs/show_bug.cgi?id=21627
1030 llvm::InitializeNativeTarget(); 1186 llvm::InitializeNativeTarget();
1031 llvm::InitializeNativeTargetAsmParser(); 1187 llvm::InitializeNativeTargetAsmParser();
1032 llvm::cl::OptionCategory category( 1188 llvm::cl::OptionCategory category(
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
1198 // same method. 1354 // same method.
1199 is_blink_method)); 1355 is_blink_method));
1200 MethodDeclRewriter method_decl_rewriter(&replacements); 1356 MethodDeclRewriter method_decl_rewriter(&replacements);
1201 match_finder.addMatcher(method_decl_matcher, &method_decl_rewriter); 1357 match_finder.addMatcher(method_decl_matcher, &method_decl_rewriter);
1202 1358
1203 // Method references in a non-member context ======== 1359 // Method references in a non-member context ========
1204 // Given 1360 // Given
1205 // S s; 1361 // S s;
1206 // s.g(); 1362 // s.g();
1207 // void (S::*p)() = &S::g; 1363 // void (S::*p)() = &S::g;
1208 // matches |&S::g| but not |s.g()|. 1364 // matches |&S::g| but not |s.g|.
1209 auto method_ref_matcher = id( 1365 auto method_ref_matcher = id(
1210 "expr", declRefExpr(to(method_decl_matcher), 1366 "expr", declRefExpr(to(method_decl_matcher),
1211 // Ignore template substitutions. 1367 // Ignore template substitutions.
1212 unless(hasAncestor(substNonTypeTemplateParmExpr())))); 1368 unless(hasAncestor(substNonTypeTemplateParmExpr()))));
1213 1369
1214 MethodRefRewriter method_ref_rewriter(&replacements); 1370 MethodRefRewriter method_ref_rewriter(&replacements);
1215 match_finder.addMatcher(method_ref_matcher, &method_ref_rewriter); 1371 match_finder.addMatcher(method_ref_matcher, &method_ref_rewriter);
1216 1372
1217 // Method references in a member context ======== 1373 // Method references in a member context ========
1218 // Given 1374 // Given
1219 // S s; 1375 // S s;
1220 // s.g(); 1376 // s.g();
1221 // void (S::*p)() = &S::g; 1377 // void (S::*p)() = &S::g;
1222 // matches |s.g()| but not |&S::g|. 1378 // matches |s.g| but not |&S::g|.
1223 auto method_member_matcher = 1379 auto method_member_matcher =
1224 id("expr", memberExpr(member(method_decl_matcher))); 1380 id("expr", memberExpr(member(method_decl_matcher)));
1225 1381
1226 MethodMemberRewriter method_member_rewriter(&replacements); 1382 MethodMemberRewriter method_member_rewriter(&replacements);
1227 match_finder.addMatcher(method_member_matcher, &method_member_rewriter); 1383 match_finder.addMatcher(method_member_matcher, &method_member_rewriter);
1228 1384
1229 // Initializers ======== 1385 // Initializers ========
1230 // Given 1386 // Given
1231 // struct S { 1387 // struct S {
1232 // int x; 1388 // int x;
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
1381 // }; 1537 // };
1382 // matches |T::foo| and |x.bar|. 1538 // matches |T::foo| and |x.bar|.
1383 auto cxx_dependent_scope_member_expr_matcher = 1539 auto cxx_dependent_scope_member_expr_matcher =
1384 expr(id("expr", cxxDependentScopeMemberExpr( 1540 expr(id("expr", cxxDependentScopeMemberExpr(
1385 hasMemberFromType(blink_qual_type_matcher)))); 1541 hasMemberFromType(blink_qual_type_matcher))));
1386 CXXDependentScopeMemberExprRewriter cxx_dependent_scope_member_expr_rewriter( 1542 CXXDependentScopeMemberExprRewriter cxx_dependent_scope_member_expr_rewriter(
1387 &replacements); 1543 &replacements);
1388 match_finder.addMatcher(cxx_dependent_scope_member_expr_matcher, 1544 match_finder.addMatcher(cxx_dependent_scope_member_expr_matcher,
1389 &cxx_dependent_scope_member_expr_rewriter); 1545 &cxx_dependent_scope_member_expr_rewriter);
1390 1546
1547 // GMock calls lookup ========
1548 // Given
1549 // EXPECT_CALL(obj, myMethod(...))
1550 // will match obj.gmock_myMethod(...) call generated by the macro
1551 // (but only if it mocks a Blink method).
1552 auto gmock_member_matcher =
1553 id("expr", memberExpr(hasDeclaration(
1554 decl(cxxMethodDecl(mocksMethod(method_decl_matcher))))));
1555 GMockMemberRewriter gmock_member_rewriter(&replacements);
1556 match_finder.addMatcher(gmock_member_matcher, &gmock_member_rewriter);
1557
1558 // Run all the matchers.
1559 SourceFileCallbacks source_file_callbacks;
1560 source_file_callbacks.AddPPCallbacks(
1561 gmock_member_rewriter.CreatePreprocessorCallbacks());
1391 std::unique_ptr<clang::tooling::FrontendActionFactory> factory = 1562 std::unique_ptr<clang::tooling::FrontendActionFactory> factory =
1392 clang::tooling::newFrontendActionFactory(&match_finder); 1563 clang::tooling::newFrontendActionFactory(&match_finder,
1564 &source_file_callbacks);
1393 int result = tool.run(factory.get()); 1565 int result = tool.run(factory.get());
1394 if (result != 0) 1566 if (result != 0)
1395 return result; 1567 return result;
1396 1568
1397 // Supplemental data for the Blink rename rebase helper. 1569 // Supplemental data for the Blink rename rebase helper.
1398 // TODO(dcheng): There's a lot of match rewriters missing from this list. 1570 // TODO(dcheng): There's a lot of match rewriters missing from this list.
1399 llvm::outs() << "==== BEGIN TRACKED EDITS ====\n"; 1571 llvm::outs() << "==== BEGIN TRACKED EDITS ====\n";
1400 field_decl_rewriter.edit_tracker().SerializeTo("var", llvm::outs()); 1572 field_decl_rewriter.edit_tracker().SerializeTo("var", llvm::outs());
1401 var_decl_rewriter.edit_tracker().SerializeTo("var", llvm::outs()); 1573 var_decl_rewriter.edit_tracker().SerializeTo("var", llvm::outs());
1402 enum_member_decl_rewriter.edit_tracker().SerializeTo("enu", llvm::outs()); 1574 enum_member_decl_rewriter.edit_tracker().SerializeTo("enu", llvm::outs());
1403 function_decl_rewriter.edit_tracker().SerializeTo("fun", llvm::outs()); 1575 function_decl_rewriter.edit_tracker().SerializeTo("fun", llvm::outs());
1404 method_decl_rewriter.edit_tracker().SerializeTo("fun", llvm::outs()); 1576 method_decl_rewriter.edit_tracker().SerializeTo("fun", llvm::outs());
1405 llvm::outs() << "==== END TRACKED EDITS ====\n"; 1577 llvm::outs() << "==== END TRACKED EDITS ====\n";
1406 1578
1407 // Serialization format is documented in tools/clang/scripts/run_tool.py 1579 // Serialization format is documented in tools/clang/scripts/run_tool.py
1408 llvm::outs() << "==== BEGIN EDITS ====\n"; 1580 llvm::outs() << "==== BEGIN EDITS ====\n";
1409 for (const auto& r : replacements) { 1581 for (const auto& r : replacements) {
1410 std::string replacement_text = r.getReplacementText().str(); 1582 std::string replacement_text = r.getReplacementText().str();
1411 std::replace(replacement_text.begin(), replacement_text.end(), '\n', '\0'); 1583 std::replace(replacement_text.begin(), replacement_text.end(), '\n', '\0');
1412 llvm::outs() << "r:::" << r.getFilePath() << ":::" << r.getOffset() 1584 llvm::outs() << "r:::" << r.getFilePath() << ":::" << r.getOffset()
1413 << ":::" << r.getLength() << ":::" << replacement_text << "\n"; 1585 << ":::" << r.getLength() << ":::" << replacement_text << "\n";
1414 } 1586 }
1415 llvm::outs() << "==== END EDITS ====\n"; 1587 llvm::outs() << "==== END EDITS ====\n";
1416 1588
1417 return 0; 1589 return 0;
1418 } 1590 }
OLDNEW
« no previous file with comments | « no previous file | tools/clang/rewrite_to_chrome_style/tests/gmock-expected.cc » ('j') | tools/clang/scripts/run_tool.py » ('J')

Powered by Google App Engine
This is Rietveld 408576698