| Index: tools/clang/base_bind_rewriters/BaseBindRewriters.cpp
|
| diff --git a/tools/clang/base_bind_rewriters/BaseBindRewriters.cpp b/tools/clang/base_bind_rewriters/BaseBindRewriters.cpp
|
| index 55877c3055e83ff786d83e52c97a7aa31096960f..5d4fc132161be9b17fd1935ee4a61c3befada9fe 100644
|
| --- a/tools/clang/base_bind_rewriters/BaseBindRewriters.cpp
|
| +++ b/tools/clang/base_bind_rewriters/BaseBindRewriters.cpp
|
| @@ -29,42 +29,51 @@ using Replacements = std::vector<clang::tooling::Replacement>;
|
|
|
| namespace {
|
|
|
| -// Remove unneeded scoped_refptr<>::get on a receivers of method bind.
|
| +// Replace base::Bind() to base::BindOnce() where resulting base::Callback is
|
| +// implicitly converted into base::OnceCallback.
|
| // Example:
|
| // // Before
|
| -// scoped_refptr<Foo> foo;
|
| -// base::Bind(&Foo::Bar, foo.get());
|
| +// base::PostTask(FROM_HERE, base::Bind(&Foo));
|
| +// base::OnceCallback<void()> cb = base::Bind(&Foo);
|
| //
|
| // // After
|
| -// scoped_refptr<Foo> foo;
|
| -// base::Bind(&Foo::Bar, foo);
|
| -//
|
| -class ScopedRefptrGetRewriter : public MatchFinder::MatchCallback {
|
| +// base::PostTask(FROM_HERE, base::BindOnce(&Foo));
|
| +// base::OnceCallback<void()> cb = base::BindOnce(&Foo);
|
| +class BindOnceRewriter : public MatchFinder::MatchCallback {
|
| public:
|
| - explicit ScopedRefptrGetRewriter(Replacements* replacements)
|
| + explicit BindOnceRewriter(Replacements* replacements)
|
| : replacements_(replacements) {}
|
|
|
| StatementMatcher GetMatcher() {
|
| - auto is_bind_call = callee(namedDecl(hasName("::base::Bind")));
|
| - auto is_method_bind = hasArgument(0, hasType(memberPointerType()));
|
| - auto is_raw_pointer_receiver = hasArgument(1, hasType(pointerType()));
|
| - auto is_scoped_refptr_get_call =
|
| - cxxMemberCallExpr(thisPointerType(namedDecl(hasName("scoped_refptr"))),
|
| - callee(namedDecl(hasName("get"))));
|
| - return callExpr(is_bind_call, is_method_bind, is_raw_pointer_receiver,
|
| - hasArgument(1, is_scoped_refptr_get_call),
|
| - hasArgument(1, stmt().bind("target")));
|
| + auto is_once_callback = hasType(classTemplateSpecializationDecl(
|
| + hasName("::base::Callback"),
|
| + hasTemplateArgument(1, equalsIntegralValue("0")),
|
| + hasTemplateArgument(2, equalsIntegralValue("0"))));
|
| + auto is_repeating_callback = hasType(classTemplateSpecializationDecl(
|
| + hasName("::base::Callback"),
|
| + hasTemplateArgument(1, equalsIntegralValue("1")),
|
| + hasTemplateArgument(2, equalsIntegralValue("1"))));
|
| +
|
| + auto bind_call =
|
| + callExpr(callee(namedDecl(hasName("::base::Bind")))).bind("target");
|
| + auto parameter_construction =
|
| + cxxConstructExpr(is_repeating_callback, argumentCountIs(1),
|
| + hasArgument(0, ignoringImplicit(bind_call)));
|
| + auto constructor_conversion = cxxConstructExpr(
|
| + is_once_callback, argumentCountIs(1),
|
| + hasArgument(0, ignoringImplicit(parameter_construction)));
|
| + auto implicit_conversion = implicitCastExpr(
|
| + is_once_callback, hasSourceExpression(constructor_conversion));
|
| + return implicit_conversion;
|
| }
|
|
|
| void run(const MatchFinder::MatchResult& result) override {
|
| - auto* target = result.Nodes.getNodeAs<clang::CXXMemberCallExpr>("target");
|
| - auto* member = llvm::cast<clang::MemberExpr>(target->getCallee());
|
| - assert(target && member && "Unexpected match! No Expr captured!");
|
| + auto* target = result.Nodes.getNodeAs<clang::CallExpr>("target");
|
| + auto* callee = target->getCallee();
|
| auto range = clang::CharSourceRange::getTokenRange(
|
| - result.SourceManager->getSpellingLoc(member->getOperatorLoc()),
|
| - result.SourceManager->getSpellingLoc(target->getLocEnd()));
|
| -
|
| - replacements_->emplace_back(*result.SourceManager, range, "");
|
| + result.SourceManager->getSpellingLoc(callee->getLocEnd()),
|
| + result.SourceManager->getSpellingLoc(callee->getLocEnd()));
|
| + replacements_->emplace_back(*result.SourceManager, range, "BindOnce");
|
| }
|
|
|
| private:
|
| @@ -87,10 +96,8 @@ int main(int argc, const char* argv[]) {
|
| MatchFinder match_finder;
|
| std::vector<clang::tooling::Replacement> replacements;
|
|
|
| -
|
| - ScopedRefptrGetRewriter scoped_refptr_rewriter(&replacements);
|
| - match_finder.addMatcher(scoped_refptr_rewriter.GetMatcher(),
|
| - &scoped_refptr_rewriter);
|
| + BindOnceRewriter bind_once_rewriter(&replacements);
|
| + match_finder.addMatcher(bind_once_rewriter.GetMatcher(), &bind_once_rewriter);
|
|
|
| std::unique_ptr<clang::tooling::FrontendActionFactory> factory =
|
| clang::tooling::newFrontendActionFactory(&match_finder);
|
|
|