xref: /aosp_15_r20/external/clang/lib/Tooling/RefactoringCallbacks.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li //===--- RefactoringCallbacks.cpp - Structural query framework ------------===//
2*67e74705SXin Li //
3*67e74705SXin Li //                     The LLVM Compiler Infrastructure
4*67e74705SXin Li //
5*67e74705SXin Li // This file is distributed under the University of Illinois Open Source
6*67e74705SXin Li // License. See LICENSE.TXT for details.
7*67e74705SXin Li //
8*67e74705SXin Li //===----------------------------------------------------------------------===//
9*67e74705SXin Li //
10*67e74705SXin Li //
11*67e74705SXin Li //===----------------------------------------------------------------------===//
12*67e74705SXin Li #include "clang/Lex/Lexer.h"
13*67e74705SXin Li #include "clang/Tooling/RefactoringCallbacks.h"
14*67e74705SXin Li 
15*67e74705SXin Li namespace clang {
16*67e74705SXin Li namespace tooling {
17*67e74705SXin Li 
RefactoringCallback()18*67e74705SXin Li RefactoringCallback::RefactoringCallback() {}
getReplacements()19*67e74705SXin Li tooling::Replacements &RefactoringCallback::getReplacements() {
20*67e74705SXin Li   return Replace;
21*67e74705SXin Li }
22*67e74705SXin Li 
replaceStmtWithText(SourceManager & Sources,const Stmt & From,StringRef Text)23*67e74705SXin Li static Replacement replaceStmtWithText(SourceManager &Sources,
24*67e74705SXin Li                                        const Stmt &From,
25*67e74705SXin Li                                        StringRef Text) {
26*67e74705SXin Li   return tooling::Replacement(Sources, CharSourceRange::getTokenRange(
27*67e74705SXin Li       From.getSourceRange()), Text);
28*67e74705SXin Li }
replaceStmtWithStmt(SourceManager & Sources,const Stmt & From,const Stmt & To)29*67e74705SXin Li static Replacement replaceStmtWithStmt(SourceManager &Sources,
30*67e74705SXin Li                                        const Stmt &From,
31*67e74705SXin Li                                        const Stmt &To) {
32*67e74705SXin Li   return replaceStmtWithText(Sources, From, Lexer::getSourceText(
33*67e74705SXin Li       CharSourceRange::getTokenRange(To.getSourceRange()),
34*67e74705SXin Li       Sources, LangOptions()));
35*67e74705SXin Li }
36*67e74705SXin Li 
ReplaceStmtWithText(StringRef FromId,StringRef ToText)37*67e74705SXin Li ReplaceStmtWithText::ReplaceStmtWithText(StringRef FromId, StringRef ToText)
38*67e74705SXin Li     : FromId(FromId), ToText(ToText) {}
39*67e74705SXin Li 
run(const ast_matchers::MatchFinder::MatchResult & Result)40*67e74705SXin Li void ReplaceStmtWithText::run(
41*67e74705SXin Li     const ast_matchers::MatchFinder::MatchResult &Result) {
42*67e74705SXin Li   if (const Stmt *FromMatch = Result.Nodes.getStmtAs<Stmt>(FromId)) {
43*67e74705SXin Li     Replace.insert(tooling::Replacement(
44*67e74705SXin Li         *Result.SourceManager,
45*67e74705SXin Li         CharSourceRange::getTokenRange(FromMatch->getSourceRange()),
46*67e74705SXin Li         ToText));
47*67e74705SXin Li   }
48*67e74705SXin Li }
49*67e74705SXin Li 
ReplaceStmtWithStmt(StringRef FromId,StringRef ToId)50*67e74705SXin Li ReplaceStmtWithStmt::ReplaceStmtWithStmt(StringRef FromId, StringRef ToId)
51*67e74705SXin Li     : FromId(FromId), ToId(ToId) {}
52*67e74705SXin Li 
run(const ast_matchers::MatchFinder::MatchResult & Result)53*67e74705SXin Li void ReplaceStmtWithStmt::run(
54*67e74705SXin Li     const ast_matchers::MatchFinder::MatchResult &Result) {
55*67e74705SXin Li   const Stmt *FromMatch = Result.Nodes.getStmtAs<Stmt>(FromId);
56*67e74705SXin Li   const Stmt *ToMatch = Result.Nodes.getStmtAs<Stmt>(ToId);
57*67e74705SXin Li   if (FromMatch && ToMatch)
58*67e74705SXin Li     Replace.insert(replaceStmtWithStmt(
59*67e74705SXin Li         *Result.SourceManager, *FromMatch, *ToMatch));
60*67e74705SXin Li }
61*67e74705SXin Li 
ReplaceIfStmtWithItsBody(StringRef Id,bool PickTrueBranch)62*67e74705SXin Li ReplaceIfStmtWithItsBody::ReplaceIfStmtWithItsBody(StringRef Id,
63*67e74705SXin Li                                                    bool PickTrueBranch)
64*67e74705SXin Li     : Id(Id), PickTrueBranch(PickTrueBranch) {}
65*67e74705SXin Li 
run(const ast_matchers::MatchFinder::MatchResult & Result)66*67e74705SXin Li void ReplaceIfStmtWithItsBody::run(
67*67e74705SXin Li     const ast_matchers::MatchFinder::MatchResult &Result) {
68*67e74705SXin Li   if (const IfStmt *Node = Result.Nodes.getStmtAs<IfStmt>(Id)) {
69*67e74705SXin Li     const Stmt *Body = PickTrueBranch ? Node->getThen() : Node->getElse();
70*67e74705SXin Li     if (Body) {
71*67e74705SXin Li       Replace.insert(replaceStmtWithStmt(*Result.SourceManager, *Node, *Body));
72*67e74705SXin Li     } else if (!PickTrueBranch) {
73*67e74705SXin Li       // If we want to use the 'else'-branch, but it doesn't exist, delete
74*67e74705SXin Li       // the whole 'if'.
75*67e74705SXin Li       Replace.insert(replaceStmtWithText(*Result.SourceManager, *Node, ""));
76*67e74705SXin Li     }
77*67e74705SXin Li   }
78*67e74705SXin Li }
79*67e74705SXin Li 
80*67e74705SXin Li } // end namespace tooling
81*67e74705SXin Li } // end namespace clang
82