OLD | NEW |
(Empty) | |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "ListValueRewriter.h" |
| 6 |
| 7 #include <assert.h> |
| 8 #include <algorithm> |
| 9 |
| 10 #include "clang/AST/ASTContext.h" |
| 11 #include "clang/ASTMatchers/ASTMatchFinder.h" |
| 12 #include "clang/ASTMatchers/ASTMatchers.h" |
| 13 #include "clang/ASTMatchers/ASTMatchersMacros.h" |
| 14 #include "clang/Basic/CharInfo.h" |
| 15 #include "clang/Basic/SourceManager.h" |
| 16 #include "clang/Frontend/FrontendActions.h" |
| 17 #include "clang/Lex/Lexer.h" |
| 18 #include "clang/Tooling/Refactoring.h" |
| 19 #include "llvm/ADT/STLExtras.h" |
| 20 |
| 21 using namespace clang::ast_matchers; |
| 22 using clang::tooling::Replacement; |
| 23 using clang::tooling::Replacements; |
| 24 using llvm::StringRef; |
| 25 |
| 26 ListValueRewriter::AppendCallback::AppendCallback(Replacements* replacements) |
| 27 : replacements_(replacements) {} |
| 28 |
| 29 void ListValueRewriter::AppendCallback::run( |
| 30 const MatchFinder::MatchResult& result) { |
| 31 // Delete `new base::*Value(' and `)'. |
| 32 auto* newExpr = result.Nodes.getNodeAs<clang::CXXNewExpr>("newExpr"); |
| 33 auto* argExpr = result.Nodes.getNodeAs<clang::Expr>("argExpr"); |
| 34 |
| 35 clang::CharSourceRange pre_arg_range = clang::CharSourceRange::getCharRange( |
| 36 newExpr->getLocStart(), argExpr->getLocStart()); |
| 37 replacements_->emplace(*result.SourceManager, pre_arg_range, ""); |
| 38 |
| 39 clang::CharSourceRange post_arg_range = |
| 40 clang::CharSourceRange::getTokenRange(newExpr->getLocEnd()); |
| 41 replacements_->emplace(*result.SourceManager, post_arg_range, ""); |
| 42 } |
| 43 |
| 44 ListValueRewriter::AppendBooleanCallback::AppendBooleanCallback( |
| 45 Replacements* replacements) |
| 46 : AppendCallback(replacements) {} |
| 47 |
| 48 void ListValueRewriter::AppendBooleanCallback::run( |
| 49 const MatchFinder::MatchResult& result) { |
| 50 // Replace 'Append' with 'AppendBoolean'. |
| 51 auto* callExpr = result.Nodes.getNodeAs<clang::CXXMemberCallExpr>("callExpr"); |
| 52 |
| 53 clang::CharSourceRange call_range = |
| 54 clang::CharSourceRange::getTokenRange(callExpr->getExprLoc()); |
| 55 replacements_->emplace(*result.SourceManager, call_range, "AppendBoolean"); |
| 56 |
| 57 AppendCallback::run(result); |
| 58 } |
| 59 |
| 60 ListValueRewriter::AppendIntegerCallback::AppendIntegerCallback( |
| 61 Replacements* replacements) |
| 62 : AppendCallback(replacements) {} |
| 63 |
| 64 void ListValueRewriter::AppendIntegerCallback::run( |
| 65 const MatchFinder::MatchResult& result) { |
| 66 // Replace 'Append' with 'AppendInteger'. |
| 67 auto* callExpr = result.Nodes.getNodeAs<clang::CXXMemberCallExpr>("callExpr"); |
| 68 |
| 69 clang::CharSourceRange call_range = |
| 70 clang::CharSourceRange::getTokenRange(callExpr->getExprLoc()); |
| 71 replacements_->emplace(*result.SourceManager, call_range, "AppendInteger"); |
| 72 |
| 73 AppendCallback::run(result); |
| 74 } |
| 75 |
| 76 ListValueRewriter::AppendDoubleCallback::AppendDoubleCallback( |
| 77 Replacements* replacements) |
| 78 : AppendCallback(replacements) {} |
| 79 |
| 80 void ListValueRewriter::AppendDoubleCallback::run( |
| 81 const MatchFinder::MatchResult& result) { |
| 82 // Replace 'Append' with 'AppendDouble'. |
| 83 auto* callExpr = result.Nodes.getNodeAs<clang::CXXMemberCallExpr>("callExpr"); |
| 84 |
| 85 clang::CharSourceRange call_range = |
| 86 clang::CharSourceRange::getTokenRange(callExpr->getExprLoc()); |
| 87 replacements_->emplace(*result.SourceManager, call_range, "AppendDouble"); |
| 88 |
| 89 AppendCallback::run(result); |
| 90 } |
| 91 |
| 92 ListValueRewriter::AppendStringCallback::AppendStringCallback( |
| 93 Replacements* replacements) |
| 94 : AppendCallback(replacements) {} |
| 95 |
| 96 void ListValueRewriter::AppendStringCallback::run( |
| 97 const MatchFinder::MatchResult& result) { |
| 98 // Replace 'Append' with 'AppendString'. |
| 99 auto* callExpr = result.Nodes.getNodeAs<clang::CXXMemberCallExpr>("callExpr"); |
| 100 |
| 101 clang::CharSourceRange call_range = |
| 102 clang::CharSourceRange::getTokenRange(callExpr->getExprLoc()); |
| 103 replacements_->emplace(*result.SourceManager, call_range, "AppendString"); |
| 104 |
| 105 AppendCallback::run(result); |
| 106 } |
| 107 |
| 108 ListValueRewriter::ListValueRewriter(Replacements* replacements) |
| 109 : append_boolean_callback_(replacements), |
| 110 append_integer_callback_(replacements), |
| 111 append_double_callback_(replacements), |
| 112 append_string_callback_(replacements) {} |
| 113 |
| 114 void ListValueRewriter::RegisterMatchers(MatchFinder* match_finder) { |
| 115 auto is_list_append = |
| 116 allOf(callee(cxxMethodDecl(hasName("::base::ListValue::Append"))), |
| 117 argumentCountIs(1)); |
| 118 |
| 119 // base::ListValue::Append(new base::FundamentalValue(bool)) |
| 120 // => base::ListValue::AppendBoolean() |
| 121 match_finder->addMatcher( |
| 122 id("callExpr", |
| 123 cxxMemberCallExpr( |
| 124 is_list_append, |
| 125 hasArgument( |
| 126 0, ignoringParenImpCasts(id( |
| 127 "newExpr", |
| 128 cxxNewExpr(has(cxxConstructExpr( |
| 129 hasDeclaration(cxxMethodDecl(hasName( |
| 130 "::base::FundamentalValue::FundamentalValue"))), |
| 131 argumentCountIs(1), |
| 132 hasArgument( |
| 133 0, id("argExpr", |
| 134 expr(hasType(booleanType())))))))))))), |
| 135 &append_boolean_callback_); |
| 136 |
| 137 // base::ListValue::Append(new base::FundamentalValue(int)) |
| 138 // => base::ListValue::AppendInteger() |
| 139 match_finder->addMatcher( |
| 140 id("callExpr", |
| 141 cxxMemberCallExpr( |
| 142 is_list_append, |
| 143 hasArgument( |
| 144 0, |
| 145 ignoringParenImpCasts(id( |
| 146 "newExpr", |
| 147 cxxNewExpr(has(cxxConstructExpr( |
| 148 hasDeclaration(cxxMethodDecl(hasName( |
| 149 "::base::FundamentalValue::FundamentalValue"))), |
| 150 argumentCountIs(1), |
| 151 hasArgument(0, id("argExpr", |
| 152 expr(hasType(isInteger()), |
| 153 unless(hasType( |
| 154 booleanType()))))))))))))), |
| 155 &append_integer_callback_); |
| 156 |
| 157 // base::ListValue::Append(new base::FundamentalValue(double)) |
| 158 // => base::ListValue::AppendDouble() |
| 159 match_finder->addMatcher( |
| 160 id("callExpr", |
| 161 cxxMemberCallExpr( |
| 162 is_list_append, |
| 163 hasArgument( |
| 164 0, ignoringParenImpCasts(id( |
| 165 "newExpr", |
| 166 cxxNewExpr(has(cxxConstructExpr( |
| 167 hasDeclaration(cxxMethodDecl(hasName( |
| 168 "::base::FundamentalValue::FundamentalValue"))), |
| 169 argumentCountIs(1), |
| 170 hasArgument( |
| 171 0, id("argExpr", |
| 172 expr(hasType( |
| 173 realFloatingPointType())))))))))))), |
| 174 &append_double_callback_); |
| 175 |
| 176 // base::ListValue::Append(new base::StringValue(...)) |
| 177 // => base::ListValue::AppendString() |
| 178 match_finder->addMatcher( |
| 179 id("callExpr", |
| 180 cxxMemberCallExpr( |
| 181 is_list_append, |
| 182 hasArgument( |
| 183 0, ignoringParenImpCasts(id( |
| 184 "newExpr", |
| 185 cxxNewExpr(has(cxxConstructExpr( |
| 186 hasDeclaration(cxxMethodDecl( |
| 187 hasName("::base::StringValue::StringValue"))), |
| 188 argumentCountIs(1), |
| 189 hasArgument(0, id("argExpr", expr())))))))))), |
| 190 &append_string_callback_); |
| 191 } |
OLD | NEW |