OLD | NEW |
---|---|
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 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 | 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 #include "ListValueRewriter.h" | 5 #include "ListValueRewriter.h" |
6 | 6 |
7 #include <assert.h> | 7 #include <assert.h> |
8 #include <algorithm> | 8 #include <algorithm> |
9 | 9 |
10 #include "clang/AST/ASTContext.h" | 10 #include "clang/AST/ASTContext.h" |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
101 // Replace 'Append' with 'AppendString'. | 101 // Replace 'Append' with 'AppendString'. |
102 auto* callExpr = result.Nodes.getNodeAs<clang::CXXMemberCallExpr>("callExpr"); | 102 auto* callExpr = result.Nodes.getNodeAs<clang::CXXMemberCallExpr>("callExpr"); |
103 | 103 |
104 clang::CharSourceRange call_range = | 104 clang::CharSourceRange call_range = |
105 clang::CharSourceRange::getTokenRange(callExpr->getExprLoc()); | 105 clang::CharSourceRange::getTokenRange(callExpr->getExprLoc()); |
106 replacements_->emplace(*result.SourceManager, call_range, "AppendString"); | 106 replacements_->emplace(*result.SourceManager, call_range, "AppendString"); |
107 | 107 |
108 AppendCallback::run(result); | 108 AppendCallback::run(result); |
109 } | 109 } |
110 | 110 |
111 ListValueRewriter::AppendReleasedUniquePtrCallback:: | |
112 AppendReleasedUniquePtrCallback(Replacements* replacements) | |
113 : replacements_(replacements) {} | |
114 | |
115 void ListValueRewriter::AppendReleasedUniquePtrCallback::run( | |
116 const MatchFinder::MatchResult& result) { | |
117 auto* object_expr = result.Nodes.getNodeAs<clang::Expr>("objectExpr"); | |
118 bool arg_is_rvalue = object_expr->Classify(*result.Context).isRValue(); | |
119 | |
120 // Remove .release() | |
121 auto* member_call = | |
122 result.Nodes.getNodeAs<clang::CXXMemberCallExpr>("memberCall"); | |
123 auto* member_expr = result.Nodes.getNodeAs<clang::MemberExpr>("memberExpr"); | |
vmpstr
2016/06/09 00:15:59
Does this always find the release/last method?
I'
dcheng
2016/06/09 00:57:12
This will match the rvalue reference case, with th
| |
124 clang::CharSourceRange release_range = clang::CharSourceRange::getTokenRange( | |
125 member_expr->getOperatorLoc(), member_call->getLocEnd()); | |
126 replacements_->emplace(*result.SourceManager, release_range, | |
127 arg_is_rvalue ? "" : ")"); | |
128 | |
129 if (arg_is_rvalue) | |
130 return; | |
131 | |
132 // Insert `std::move(' for non-rvalue expressions. | |
133 clang::CharSourceRange insertion_range = clang::CharSourceRange::getCharRange( | |
134 object_expr->getLocStart(), object_expr->getLocStart()); | |
135 replacements_->emplace(*result.SourceManager, insertion_range, "std::move("); | |
136 } | |
137 | |
111 ListValueRewriter::ListValueRewriter(Replacements* replacements) | 138 ListValueRewriter::ListValueRewriter(Replacements* replacements) |
112 : append_boolean_callback_(replacements), | 139 : append_boolean_callback_(replacements), |
113 append_integer_callback_(replacements), | 140 append_integer_callback_(replacements), |
114 append_double_callback_(replacements), | 141 append_double_callback_(replacements), |
115 append_string_callback_(replacements) {} | 142 append_string_callback_(replacements), |
143 append_released_unique_ptr_callback_(replacements) {} | |
116 | 144 |
117 void ListValueRewriter::RegisterMatchers(MatchFinder* match_finder) { | 145 void ListValueRewriter::RegisterMatchers(MatchFinder* match_finder) { |
118 auto is_list_append = | 146 auto is_list_append = |
119 allOf(callee(cxxMethodDecl(hasName("::base::ListValue::Append"))), | 147 allOf(callee(cxxMethodDecl(hasName("::base::ListValue::Append"))), |
120 argumentCountIs(1)); | 148 argumentCountIs(1)); |
121 | 149 |
122 // base::ListValue::Append(new base::FundamentalValue(bool)) | 150 // base::ListValue::Append(new base::FundamentalValue(bool)) |
123 // => base::ListValue::AppendBoolean() | 151 // => base::ListValue::AppendBoolean() |
124 match_finder->addMatcher( | 152 match_finder->addMatcher( |
125 id("callExpr", | 153 id("callExpr", |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
184 is_list_append, | 212 is_list_append, |
185 hasArgument( | 213 hasArgument( |
186 0, ignoringParenImpCasts(id( | 214 0, ignoringParenImpCasts(id( |
187 "newExpr", | 215 "newExpr", |
188 cxxNewExpr(has(cxxConstructExpr( | 216 cxxNewExpr(has(cxxConstructExpr( |
189 hasDeclaration(cxxMethodDecl( | 217 hasDeclaration(cxxMethodDecl( |
190 hasName("::base::StringValue::StringValue"))), | 218 hasName("::base::StringValue::StringValue"))), |
191 argumentCountIs(1), | 219 argumentCountIs(1), |
192 hasArgument(0, id("argExpr", expr())))))))))), | 220 hasArgument(0, id("argExpr", expr())))))))))), |
193 &append_string_callback_); | 221 &append_string_callback_); |
222 | |
223 auto is_unique_ptr_release = | |
224 allOf(callee(cxxMethodDecl( | |
225 hasName("release"), | |
226 ofClass(cxxRecordDecl(hasName("::std::unique_ptr"))))), | |
227 argumentCountIs(0)); | |
228 | |
229 // base::ListValue::Append(ReturnsUniquePtr().release()) | |
230 // => base::ListValue::Append(ReturnsUniquePtr()) | |
231 // or | |
232 // base::ListValue::Append(unique_ptr_var.release()) | |
233 // => base::ListValue::Append(std::move(unique_ptr_var)) | |
234 match_finder->addMatcher( | |
235 cxxMemberCallExpr( | |
236 is_list_append, | |
237 hasArgument( | |
238 0, ignoringParenImpCasts( | |
239 id("memberCall", | |
240 cxxMemberCallExpr(has(id("memberExpr", memberExpr())), | |
241 is_unique_ptr_release, | |
242 on(id("objectExpr", expr()))))))), | |
vmpstr
2016/06/09 00:15:59
:)))))))))))
| |
243 &append_released_unique_ptr_callback_); | |
194 } | 244 } |
OLD | NEW |