Index: tools/clang/value_cleanup/ListValueRewriter.cpp |
diff --git a/tools/clang/value_cleanup/ListValueRewriter.cpp b/tools/clang/value_cleanup/ListValueRewriter.cpp |
new file mode 100644 |
index 0000000000000000000000000000000000000000..d6c5cf233688e1de117bfc968c198708e6591e0a |
--- /dev/null |
+++ b/tools/clang/value_cleanup/ListValueRewriter.cpp |
@@ -0,0 +1,191 @@ |
+// Copyright 2016 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "ListValueRewriter.h" |
+ |
+#include <assert.h> |
+#include <algorithm> |
+ |
+#include "clang/AST/ASTContext.h" |
+#include "clang/ASTMatchers/ASTMatchFinder.h" |
+#include "clang/ASTMatchers/ASTMatchers.h" |
+#include "clang/ASTMatchers/ASTMatchersMacros.h" |
+#include "clang/Basic/CharInfo.h" |
+#include "clang/Basic/SourceManager.h" |
+#include "clang/Frontend/FrontendActions.h" |
+#include "clang/Lex/Lexer.h" |
+#include "clang/Tooling/Refactoring.h" |
+#include "llvm/ADT/STLExtras.h" |
+ |
+using namespace clang::ast_matchers; |
+using clang::tooling::Replacement; |
+using clang::tooling::Replacements; |
+using llvm::StringRef; |
+ |
+ListValueRewriter::AppendCallback::AppendCallback(Replacements* replacements) |
+ : replacements_(replacements) {} |
+ |
+void ListValueRewriter::AppendCallback::run( |
+ const MatchFinder::MatchResult& result) { |
+ // Delete `new base::*Value(' and `)'. |
+ auto* newExpr = result.Nodes.getNodeAs<clang::CXXNewExpr>("newExpr"); |
+ auto* argExpr = result.Nodes.getNodeAs<clang::Expr>("argExpr"); |
+ |
+ clang::CharSourceRange pre_arg_range = clang::CharSourceRange::getCharRange( |
+ newExpr->getLocStart(), argExpr->getLocStart()); |
+ replacements_->emplace(*result.SourceManager, pre_arg_range, ""); |
+ |
+ clang::CharSourceRange post_arg_range = |
+ clang::CharSourceRange::getTokenRange(newExpr->getLocEnd()); |
+ replacements_->emplace(*result.SourceManager, post_arg_range, ""); |
+} |
+ |
+ListValueRewriter::AppendBooleanCallback::AppendBooleanCallback( |
+ Replacements* replacements) |
+ : AppendCallback(replacements) {} |
+ |
+void ListValueRewriter::AppendBooleanCallback::run( |
+ const MatchFinder::MatchResult& result) { |
+ // Replace 'Append' with 'AppendBoolean'. |
+ auto* callExpr = result.Nodes.getNodeAs<clang::CXXMemberCallExpr>("callExpr"); |
+ |
+ clang::CharSourceRange call_range = |
+ clang::CharSourceRange::getTokenRange(callExpr->getExprLoc()); |
+ replacements_->emplace(*result.SourceManager, call_range, "AppendBoolean"); |
+ |
+ AppendCallback::run(result); |
+} |
+ |
+ListValueRewriter::AppendIntegerCallback::AppendIntegerCallback( |
+ Replacements* replacements) |
+ : AppendCallback(replacements) {} |
+ |
+void ListValueRewriter::AppendIntegerCallback::run( |
+ const MatchFinder::MatchResult& result) { |
+ // Replace 'Append' with 'AppendInteger'. |
+ auto* callExpr = result.Nodes.getNodeAs<clang::CXXMemberCallExpr>("callExpr"); |
+ |
+ clang::CharSourceRange call_range = |
+ clang::CharSourceRange::getTokenRange(callExpr->getExprLoc()); |
+ replacements_->emplace(*result.SourceManager, call_range, "AppendInteger"); |
+ |
+ AppendCallback::run(result); |
+} |
+ |
+ListValueRewriter::AppendDoubleCallback::AppendDoubleCallback( |
+ Replacements* replacements) |
+ : AppendCallback(replacements) {} |
+ |
+void ListValueRewriter::AppendDoubleCallback::run( |
+ const MatchFinder::MatchResult& result) { |
+ // Replace 'Append' with 'AppendDouble'. |
+ auto* callExpr = result.Nodes.getNodeAs<clang::CXXMemberCallExpr>("callExpr"); |
+ |
+ clang::CharSourceRange call_range = |
+ clang::CharSourceRange::getTokenRange(callExpr->getExprLoc()); |
+ replacements_->emplace(*result.SourceManager, call_range, "AppendDouble"); |
+ |
+ AppendCallback::run(result); |
+} |
+ |
+ListValueRewriter::AppendStringCallback::AppendStringCallback( |
+ Replacements* replacements) |
+ : AppendCallback(replacements) {} |
+ |
+void ListValueRewriter::AppendStringCallback::run( |
+ const MatchFinder::MatchResult& result) { |
+ // Replace 'Append' with 'AppendString'. |
+ auto* callExpr = result.Nodes.getNodeAs<clang::CXXMemberCallExpr>("callExpr"); |
+ |
+ clang::CharSourceRange call_range = |
+ clang::CharSourceRange::getTokenRange(callExpr->getExprLoc()); |
+ replacements_->emplace(*result.SourceManager, call_range, "AppendString"); |
+ |
+ AppendCallback::run(result); |
+} |
+ |
+ListValueRewriter::ListValueRewriter(Replacements* replacements) |
+ : append_boolean_callback_(replacements), |
+ append_integer_callback_(replacements), |
+ append_double_callback_(replacements), |
+ append_string_callback_(replacements) {} |
+ |
+void ListValueRewriter::RegisterMatchers(MatchFinder* match_finder) { |
+ auto is_list_append = |
+ allOf(callee(cxxMethodDecl(hasName("::base::ListValue::Append"))), |
+ argumentCountIs(1)); |
+ |
+ // base::ListValue::Append(new base::FundamentalValue(bool)) |
+ // => base::ListValue::AppendBoolean() |
+ match_finder->addMatcher( |
+ id("callExpr", |
+ cxxMemberCallExpr( |
+ is_list_append, |
+ hasArgument( |
+ 0, ignoringParenImpCasts(id( |
+ "newExpr", |
+ cxxNewExpr(has(cxxConstructExpr( |
+ hasDeclaration(cxxMethodDecl(hasName( |
+ "::base::FundamentalValue::FundamentalValue"))), |
+ argumentCountIs(1), |
+ hasArgument( |
+ 0, id("argExpr", |
+ expr(hasType(booleanType())))))))))))), |
+ &append_boolean_callback_); |
+ |
+ // base::ListValue::Append(new base::FundamentalValue(int)) |
+ // => base::ListValue::AppendInteger() |
+ match_finder->addMatcher( |
+ id("callExpr", |
+ cxxMemberCallExpr( |
+ is_list_append, |
+ hasArgument( |
+ 0, |
+ ignoringParenImpCasts(id( |
+ "newExpr", |
+ cxxNewExpr(has(cxxConstructExpr( |
+ hasDeclaration(cxxMethodDecl(hasName( |
+ "::base::FundamentalValue::FundamentalValue"))), |
+ argumentCountIs(1), |
+ hasArgument(0, id("argExpr", |
+ expr(hasType(isInteger()), |
+ unless(hasType( |
+ booleanType()))))))))))))), |
+ &append_integer_callback_); |
+ |
+ // base::ListValue::Append(new base::FundamentalValue(double)) |
+ // => base::ListValue::AppendDouble() |
+ match_finder->addMatcher( |
+ id("callExpr", |
+ cxxMemberCallExpr( |
+ is_list_append, |
+ hasArgument( |
+ 0, ignoringParenImpCasts(id( |
+ "newExpr", |
+ cxxNewExpr(has(cxxConstructExpr( |
+ hasDeclaration(cxxMethodDecl(hasName( |
+ "::base::FundamentalValue::FundamentalValue"))), |
+ argumentCountIs(1), |
+ hasArgument( |
+ 0, id("argExpr", |
+ expr(hasType( |
+ realFloatingPointType())))))))))))), |
+ &append_double_callback_); |
+ |
+ // base::ListValue::Append(new base::StringValue(...)) |
+ // => base::ListValue::AppendString() |
+ match_finder->addMatcher( |
+ id("callExpr", |
+ cxxMemberCallExpr( |
+ is_list_append, |
+ hasArgument( |
+ 0, ignoringParenImpCasts(id( |
+ "newExpr", |
+ cxxNewExpr(has(cxxConstructExpr( |
+ hasDeclaration(cxxMethodDecl( |
+ hasName("::base::StringValue::StringValue"))), |
+ argumentCountIs(1), |
+ hasArgument(0, id("argExpr", expr())))))))))), |
+ &append_string_callback_); |
+} |