| 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: |
| 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 Loading... |
| 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 694 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 786 StringRef actual_old_text = clang::Lexer::getSourceText( | 826 StringRef actual_old_text = clang::Lexer::getSourceText( |
| 787 range, source_manager, context.getLangOpts()); | 827 range, source_manager, context.getLangOpts()); |
| 788 if (actual_old_text != expected_old_text) | 828 if (actual_old_text != expected_old_text) |
| 789 return false; | 829 return false; |
| 790 | 830 |
| 791 if (replacement) | 831 if (replacement) |
| 792 *replacement = Replacement(source_manager, range, new_text); | 832 *replacement = Replacement(source_manager, range, new_text); |
| 793 return true; | 833 return true; |
| 794 } | 834 } |
| 795 | 835 |
| 836 virtual clang::SourceLocation GetTargetLoc( |
| 837 const MatchFinder::MatchResult& result) { |
| 838 return TargetNodeTraits<TargetNode>::GetLoc(GetTargetNode(result)); |
| 839 } |
| 840 |
| 796 void AddReplacement(const MatchFinder::MatchResult& result, | 841 void AddReplacement(const MatchFinder::MatchResult& result, |
| 797 llvm::StringRef old_name, | 842 llvm::StringRef old_name, |
| 798 std::string new_name) { | 843 std::string new_name) { |
| 799 if (old_name == new_name) | 844 if (old_name == new_name) |
| 800 return; | 845 return; |
| 801 | 846 |
| 802 clang::SourceLocation loc = | 847 clang::SourceLocation loc = GetTargetLoc(result); |
| 803 TargetNodeTraits<TargetNode>::GetLoc(GetTargetNode(result)); | 848 if (loc.isInvalid()) |
| 849 return; |
| 804 | 850 |
| 805 Replacement replacement; | 851 Replacement replacement; |
| 806 if (!GenerateReplacement(result, loc, old_name, new_name, &replacement)) | 852 if (!GenerateReplacement(result, loc, old_name, new_name, &replacement)) |
| 807 return; | 853 return; |
| 808 | 854 |
| 809 replacements_->insert(std::move(replacement)); | 855 replacements_->insert(std::move(replacement)); |
| 810 edit_tracker_.Add(*result.SourceManager, loc, old_name, new_name); | 856 edit_tracker_.Add(*result.SourceManager, loc, old_name, new_name); |
| 811 } | 857 } |
| 812 | 858 |
| 813 const EditTracker& edit_tracker() const { return edit_tracker_; } | 859 const EditTracker& edit_tracker() const { return edit_tracker_; } |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 876 using EnumConstantDeclRefRewriter = | 922 using EnumConstantDeclRefRewriter = |
| 877 DeclRewriterBase<clang::EnumConstantDecl, clang::DeclRefExpr>; | 923 DeclRewriterBase<clang::EnumConstantDecl, clang::DeclRefExpr>; |
| 878 | 924 |
| 879 using UnresolvedLookupRewriter = | 925 using UnresolvedLookupRewriter = |
| 880 DeclRewriterBase<clang::NamedDecl, clang::UnresolvedLookupExpr>; | 926 DeclRewriterBase<clang::NamedDecl, clang::UnresolvedLookupExpr>; |
| 881 using UnresolvedMemberRewriter = | 927 using UnresolvedMemberRewriter = |
| 882 DeclRewriterBase<clang::NamedDecl, clang::UnresolvedMemberExpr>; | 928 DeclRewriterBase<clang::NamedDecl, clang::UnresolvedMemberExpr>; |
| 883 | 929 |
| 884 using UsingDeclRewriter = DeclRewriterBase<clang::UsingDecl, clang::NamedDecl>; | 930 using UsingDeclRewriter = DeclRewriterBase<clang::UsingDecl, clang::NamedDecl>; |
| 885 | 931 |
| 932 class GMockMemberRewriter |
| 933 : public DeclRewriterBase<clang::CXXMethodDecl, clang::MemberExpr> { |
| 934 public: |
| 935 using Base = DeclRewriterBase<clang::CXXMethodDecl, clang::MemberExpr>; |
| 936 |
| 937 explicit GMockMemberRewriter(std::set<Replacement>* replacements) |
| 938 : Base(replacements) {} |
| 939 |
| 940 std::unique_ptr<clang::PPCallbacks> CreatePreprocessorCallbacks() { |
| 941 return llvm::make_unique<GMockMemberRewriter::PPCallbacks>(this); |
| 942 } |
| 943 |
| 944 clang::SourceLocation GetTargetLoc( |
| 945 const MatchFinder::MatchResult& result) override { |
| 946 // Find location of the gmock_##MockedMethod identifier. |
| 947 clang::SourceLocation target_loc = Base::GetTargetLoc(result); |
| 948 |
| 949 // Find location of EXPECT_CALL macro invocation. |
| 950 clang::SourceLocation macro_call_loc = |
| 951 result.SourceManager->getExpansionLoc(target_loc); |
| 952 |
| 953 // Map |macro_call_loc| to argument location (location of the method name |
| 954 // that needs renaming). |
| 955 auto it = expect_call_to_2nd_arg.find(macro_call_loc); |
| 956 if (it == expect_call_to_2nd_arg.end()) |
| 957 return clang::SourceLocation(); |
| 958 return it->second; |
| 959 } |
| 960 |
| 961 private: |
| 962 std::map<clang::SourceLocation, clang::SourceLocation> expect_call_to_2nd_arg; |
| 963 |
| 964 // Called from PPCallbacks with the locations of EXPECT_CALL macro invocation: |
| 965 // Example: |
| 966 // EXPECT_CALL(my_mock, myMethod(123, 456)); |
| 967 // ^- expansion_loc ^- actual_arg_loc |
| 968 void RecordExpectCallMacroInvocation(clang::SourceLocation expansion_loc, |
| 969 clang::SourceLocation second_arg_loc) { |
| 970 expect_call_to_2nd_arg[expansion_loc] = second_arg_loc; |
| 971 } |
| 972 |
| 973 class PPCallbacks : public clang::PPCallbacks { |
| 974 public: |
| 975 explicit PPCallbacks(GMockMemberRewriter* rewriter) : rewriter_(rewriter) {} |
| 976 ~PPCallbacks() override {} |
| 977 void MacroExpands(const clang::Token& name, |
| 978 const clang::MacroDefinition& def, |
| 979 clang::SourceRange range, |
| 980 const clang::MacroArgs* args) override { |
| 981 clang::IdentifierInfo* id = name.getIdentifierInfo(); |
| 982 if (!id) |
| 983 return; |
| 984 |
| 985 if (id->getName() != "EXPECT_CALL") |
| 986 return; |
| 987 |
| 988 if (def.getMacroInfo()->getNumArgs() != 2) |
| 989 return; |
| 990 |
| 991 // TODO(lukasza): Should check if def.getMacroInfo()->getDefinitionLoc() |
| 992 // is in testing/gmock/include/gmock/gmock-spec-builders.h but I don't |
| 993 // know how to get clang::SourceManager to call getFileName. |
| 994 |
| 995 rewriter_->RecordExpectCallMacroInvocation( |
| 996 name.getLocation(), args->getUnexpArgument(1)->getLocation()); |
| 997 } |
| 998 |
| 999 private: |
| 1000 GMockMemberRewriter* rewriter_; |
| 1001 }; |
| 1002 }; |
| 1003 |
| 886 clang::DeclarationName GetUnresolvedName( | 1004 clang::DeclarationName GetUnresolvedName( |
| 887 const clang::UnresolvedMemberExpr& expr) { | 1005 const clang::UnresolvedMemberExpr& expr) { |
| 888 return expr.getMemberName(); | 1006 return expr.getMemberName(); |
| 889 } | 1007 } |
| 890 | 1008 |
| 891 clang::DeclarationName GetUnresolvedName( | 1009 clang::DeclarationName GetUnresolvedName( |
| 892 const clang::DependentScopeDeclRefExpr& expr) { | 1010 const clang::DependentScopeDeclRefExpr& expr) { |
| 893 return expr.getDeclName(); | 1011 return expr.getDeclName(); |
| 894 } | 1012 } |
| 895 | 1013 |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1013 | 1131 |
| 1014 using UnresolvedUsingValueDeclRewriter = | 1132 using UnresolvedUsingValueDeclRewriter = |
| 1015 UnresolvedRewriterBase<clang::UnresolvedUsingValueDecl>; | 1133 UnresolvedRewriterBase<clang::UnresolvedUsingValueDecl>; |
| 1016 | 1134 |
| 1017 using DependentScopeDeclRefExprRewriter = | 1135 using DependentScopeDeclRefExprRewriter = |
| 1018 UnresolvedRewriterBase<clang::DependentScopeDeclRefExpr>; | 1136 UnresolvedRewriterBase<clang::DependentScopeDeclRefExpr>; |
| 1019 | 1137 |
| 1020 using CXXDependentScopeMemberExprRewriter = | 1138 using CXXDependentScopeMemberExprRewriter = |
| 1021 UnresolvedRewriterBase<clang::CXXDependentScopeMemberExpr>; | 1139 UnresolvedRewriterBase<clang::CXXDependentScopeMemberExpr>; |
| 1022 | 1140 |
| 1141 class SourceFileCallbacks : public clang::tooling::SourceFileCallbacks { |
| 1142 public: |
| 1143 explicit SourceFileCallbacks(GMockMemberRewriter* gmock_member_rewriter) |
| 1144 : gmock_member_rewriter_(gmock_member_rewriter) { |
| 1145 assert(gmock_member_rewriter); |
| 1146 } |
| 1147 |
| 1148 ~SourceFileCallbacks() override {} |
| 1149 |
| 1150 // clang::tooling::SourceFileCallbacks override: |
| 1151 bool handleBeginSource(clang::CompilerInstance& compiler, |
| 1152 llvm::StringRef Filename) override { |
| 1153 compiler.getPreprocessor().addPPCallbacks( |
| 1154 gmock_member_rewriter_->CreatePreprocessorCallbacks()); |
| 1155 return true; |
| 1156 } |
| 1157 |
| 1158 private: |
| 1159 GMockMemberRewriter* gmock_member_rewriter_; |
| 1160 }; |
| 1161 |
| 1023 } // namespace | 1162 } // namespace |
| 1024 | 1163 |
| 1025 static llvm::cl::extrahelp common_help(CommonOptionsParser::HelpMessage); | 1164 static llvm::cl::extrahelp common_help(CommonOptionsParser::HelpMessage); |
| 1026 | 1165 |
| 1027 int main(int argc, const char* argv[]) { | 1166 int main(int argc, const char* argv[]) { |
| 1028 // TODO(dcheng): Clang tooling should do this itself. | 1167 // TODO(dcheng): Clang tooling should do this itself. |
| 1029 // http://llvm.org/bugs/show_bug.cgi?id=21627 | 1168 // http://llvm.org/bugs/show_bug.cgi?id=21627 |
| 1030 llvm::InitializeNativeTarget(); | 1169 llvm::InitializeNativeTarget(); |
| 1031 llvm::InitializeNativeTargetAsmParser(); | 1170 llvm::InitializeNativeTargetAsmParser(); |
| 1032 llvm::cl::OptionCategory category( | 1171 llvm::cl::OptionCategory category( |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1198 // same method. | 1337 // same method. |
| 1199 is_blink_method)); | 1338 is_blink_method)); |
| 1200 MethodDeclRewriter method_decl_rewriter(&replacements); | 1339 MethodDeclRewriter method_decl_rewriter(&replacements); |
| 1201 match_finder.addMatcher(method_decl_matcher, &method_decl_rewriter); | 1340 match_finder.addMatcher(method_decl_matcher, &method_decl_rewriter); |
| 1202 | 1341 |
| 1203 // Method references in a non-member context ======== | 1342 // Method references in a non-member context ======== |
| 1204 // Given | 1343 // Given |
| 1205 // S s; | 1344 // S s; |
| 1206 // s.g(); | 1345 // s.g(); |
| 1207 // void (S::*p)() = &S::g; | 1346 // void (S::*p)() = &S::g; |
| 1208 // matches |&S::g| but not |s.g()|. | 1347 // matches |&S::g| but not |s.g|. |
| 1209 auto method_ref_matcher = id( | 1348 auto method_ref_matcher = id( |
| 1210 "expr", declRefExpr(to(method_decl_matcher), | 1349 "expr", declRefExpr(to(method_decl_matcher), |
| 1211 // Ignore template substitutions. | 1350 // Ignore template substitutions. |
| 1212 unless(hasAncestor(substNonTypeTemplateParmExpr())))); | 1351 unless(hasAncestor(substNonTypeTemplateParmExpr())))); |
| 1213 | 1352 |
| 1214 MethodRefRewriter method_ref_rewriter(&replacements); | 1353 MethodRefRewriter method_ref_rewriter(&replacements); |
| 1215 match_finder.addMatcher(method_ref_matcher, &method_ref_rewriter); | 1354 match_finder.addMatcher(method_ref_matcher, &method_ref_rewriter); |
| 1216 | 1355 |
| 1217 // Method references in a member context ======== | 1356 // Method references in a member context ======== |
| 1218 // Given | 1357 // Given |
| 1219 // S s; | 1358 // S s; |
| 1220 // s.g(); | 1359 // s.g(); |
| 1221 // void (S::*p)() = &S::g; | 1360 // void (S::*p)() = &S::g; |
| 1222 // matches |s.g()| but not |&S::g|. | 1361 // matches |s.g| but not |&S::g|. |
| 1223 auto method_member_matcher = | 1362 auto method_member_matcher = |
| 1224 id("expr", memberExpr(member(method_decl_matcher))); | 1363 id("expr", memberExpr(member(method_decl_matcher))); |
| 1225 | 1364 |
| 1226 MethodMemberRewriter method_member_rewriter(&replacements); | 1365 MethodMemberRewriter method_member_rewriter(&replacements); |
| 1227 match_finder.addMatcher(method_member_matcher, &method_member_rewriter); | 1366 match_finder.addMatcher(method_member_matcher, &method_member_rewriter); |
| 1228 | 1367 |
| 1229 // Initializers ======== | 1368 // Initializers ======== |
| 1230 // Given | 1369 // Given |
| 1231 // struct S { | 1370 // struct S { |
| 1232 // int x; | 1371 // int x; |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1381 // }; | 1520 // }; |
| 1382 // matches |T::foo| and |x.bar|. | 1521 // matches |T::foo| and |x.bar|. |
| 1383 auto cxx_dependent_scope_member_expr_matcher = | 1522 auto cxx_dependent_scope_member_expr_matcher = |
| 1384 expr(id("expr", cxxDependentScopeMemberExpr( | 1523 expr(id("expr", cxxDependentScopeMemberExpr( |
| 1385 hasMemberFromType(blink_qual_type_matcher)))); | 1524 hasMemberFromType(blink_qual_type_matcher)))); |
| 1386 CXXDependentScopeMemberExprRewriter cxx_dependent_scope_member_expr_rewriter( | 1525 CXXDependentScopeMemberExprRewriter cxx_dependent_scope_member_expr_rewriter( |
| 1387 &replacements); | 1526 &replacements); |
| 1388 match_finder.addMatcher(cxx_dependent_scope_member_expr_matcher, | 1527 match_finder.addMatcher(cxx_dependent_scope_member_expr_matcher, |
| 1389 &cxx_dependent_scope_member_expr_rewriter); | 1528 &cxx_dependent_scope_member_expr_rewriter); |
| 1390 | 1529 |
| 1530 // GMock calls lookup ======== |
| 1531 // Given |
| 1532 // EXPECT_CALL(obj, myMethod(...)) |
| 1533 // will match obj.gmock_myMethod(...) call generated by the macro |
| 1534 // (but only if it mocks a Blink method). |
| 1535 auto gmock_member_matcher = |
| 1536 id("expr", memberExpr(hasDeclaration( |
| 1537 decl(cxxMethodDecl(mocksMethod(method_decl_matcher)))))); |
| 1538 GMockMemberRewriter gmock_member_rewriter(&replacements); |
| 1539 match_finder.addMatcher(gmock_member_matcher, &gmock_member_rewriter); |
| 1540 |
| 1541 // Prepare and run the tool. |
| 1542 SourceFileCallbacks source_file_callbacks(&gmock_member_rewriter); |
| 1391 std::unique_ptr<clang::tooling::FrontendActionFactory> factory = | 1543 std::unique_ptr<clang::tooling::FrontendActionFactory> factory = |
| 1392 clang::tooling::newFrontendActionFactory(&match_finder); | 1544 clang::tooling::newFrontendActionFactory(&match_finder, |
| 1545 &source_file_callbacks); |
| 1393 int result = tool.run(factory.get()); | 1546 int result = tool.run(factory.get()); |
| 1394 if (result != 0) | 1547 if (result != 0) |
| 1395 return result; | 1548 return result; |
| 1396 | 1549 |
| 1397 // Supplemental data for the Blink rename rebase helper. | 1550 // Supplemental data for the Blink rename rebase helper. |
| 1398 // TODO(dcheng): There's a lot of match rewriters missing from this list. | 1551 // TODO(dcheng): There's a lot of match rewriters missing from this list. |
| 1399 llvm::outs() << "==== BEGIN TRACKED EDITS ====\n"; | 1552 llvm::outs() << "==== BEGIN TRACKED EDITS ====\n"; |
| 1400 field_decl_rewriter.edit_tracker().SerializeTo("var", llvm::outs()); | 1553 field_decl_rewriter.edit_tracker().SerializeTo("var", llvm::outs()); |
| 1401 var_decl_rewriter.edit_tracker().SerializeTo("var", llvm::outs()); | 1554 var_decl_rewriter.edit_tracker().SerializeTo("var", llvm::outs()); |
| 1402 enum_member_decl_rewriter.edit_tracker().SerializeTo("enu", llvm::outs()); | 1555 enum_member_decl_rewriter.edit_tracker().SerializeTo("enu", llvm::outs()); |
| 1403 function_decl_rewriter.edit_tracker().SerializeTo("fun", llvm::outs()); | 1556 function_decl_rewriter.edit_tracker().SerializeTo("fun", llvm::outs()); |
| 1404 method_decl_rewriter.edit_tracker().SerializeTo("fun", llvm::outs()); | 1557 method_decl_rewriter.edit_tracker().SerializeTo("fun", llvm::outs()); |
| 1405 llvm::outs() << "==== END TRACKED EDITS ====\n"; | 1558 llvm::outs() << "==== END TRACKED EDITS ====\n"; |
| 1406 | 1559 |
| 1407 // Serialization format is documented in tools/clang/scripts/run_tool.py | 1560 // Serialization format is documented in tools/clang/scripts/run_tool.py |
| 1408 llvm::outs() << "==== BEGIN EDITS ====\n"; | 1561 llvm::outs() << "==== BEGIN EDITS ====\n"; |
| 1409 for (const auto& r : replacements) { | 1562 for (const auto& r : replacements) { |
| 1410 std::string replacement_text = r.getReplacementText().str(); | 1563 std::string replacement_text = r.getReplacementText().str(); |
| 1411 std::replace(replacement_text.begin(), replacement_text.end(), '\n', '\0'); | 1564 std::replace(replacement_text.begin(), replacement_text.end(), '\n', '\0'); |
| 1412 llvm::outs() << "r:::" << r.getFilePath() << ":::" << r.getOffset() | 1565 llvm::outs() << "r:::" << r.getFilePath() << ":::" << r.getOffset() |
| 1413 << ":::" << r.getLength() << ":::" << replacement_text << "\n"; | 1566 << ":::" << r.getLength() << ":::" << replacement_text << "\n"; |
| 1414 } | 1567 } |
| 1415 llvm::outs() << "==== END EDITS ====\n"; | 1568 llvm::outs() << "==== END EDITS ====\n"; |
| 1416 | 1569 |
| 1417 return 0; | 1570 return 0; |
| 1418 } | 1571 } |
| OLD | NEW |