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