1239313Sdim//===--- RefactoringCallbacks.cpp - Structural query framework ------------===//
2239313Sdim//
3239313Sdim//                     The LLVM Compiler Infrastructure
4239313Sdim//
5239313Sdim// This file is distributed under the University of Illinois Open Source
6239313Sdim// License. See LICENSE.TXT for details.
7239313Sdim//
8239313Sdim//===----------------------------------------------------------------------===//
9239313Sdim//
10239313Sdim//
11239313Sdim//===----------------------------------------------------------------------===//
12239313Sdim#include "clang/Lex/Lexer.h"
13239313Sdim#include "clang/Tooling/RefactoringCallbacks.h"
14239313Sdim
15239313Sdimnamespace clang {
16239313Sdimnamespace tooling {
17239313Sdim
18239313SdimRefactoringCallback::RefactoringCallback() {}
19239313Sdimtooling::Replacements &RefactoringCallback::getReplacements() {
20239313Sdim  return Replace;
21239313Sdim}
22239313Sdim
23239313Sdimstatic Replacement replaceStmtWithText(SourceManager &Sources,
24239313Sdim                                       const Stmt &From,
25239313Sdim                                       StringRef Text) {
26239313Sdim  return tooling::Replacement(Sources, CharSourceRange::getTokenRange(
27239313Sdim      From.getSourceRange()), Text);
28239313Sdim}
29239313Sdimstatic Replacement replaceStmtWithStmt(SourceManager &Sources,
30239313Sdim                                       const Stmt &From,
31239313Sdim                                       const Stmt &To) {
32239313Sdim  return replaceStmtWithText(Sources, From, Lexer::getSourceText(
33239313Sdim      CharSourceRange::getTokenRange(To.getSourceRange()),
34239313Sdim      Sources, LangOptions()));
35239313Sdim}
36239313Sdim
37239313SdimReplaceStmtWithText::ReplaceStmtWithText(StringRef FromId, StringRef ToText)
38239313Sdim    : FromId(FromId), ToText(ToText) {}
39239313Sdim
40239313Sdimvoid ReplaceStmtWithText::run(
41239313Sdim    const ast_matchers::MatchFinder::MatchResult &Result) {
42239313Sdim  if (const Stmt *FromMatch = Result.Nodes.getStmtAs<Stmt>(FromId)) {
43239313Sdim    Replace.insert(tooling::Replacement(
44239313Sdim        *Result.SourceManager,
45239313Sdim        CharSourceRange::getTokenRange(FromMatch->getSourceRange()),
46239313Sdim        ToText));
47239313Sdim  }
48239313Sdim}
49239313Sdim
50239313SdimReplaceStmtWithStmt::ReplaceStmtWithStmt(StringRef FromId, StringRef ToId)
51239313Sdim    : FromId(FromId), ToId(ToId) {}
52239313Sdim
53239313Sdimvoid ReplaceStmtWithStmt::run(
54239313Sdim    const ast_matchers::MatchFinder::MatchResult &Result) {
55239313Sdim  const Stmt *FromMatch = Result.Nodes.getStmtAs<Stmt>(FromId);
56239313Sdim  const Stmt *ToMatch = Result.Nodes.getStmtAs<Stmt>(ToId);
57239313Sdim  if (FromMatch && ToMatch)
58239313Sdim    Replace.insert(replaceStmtWithStmt(
59239313Sdim        *Result.SourceManager, *FromMatch, *ToMatch));
60239313Sdim}
61239313Sdim
62239313SdimReplaceIfStmtWithItsBody::ReplaceIfStmtWithItsBody(StringRef Id,
63239313Sdim                                                   bool PickTrueBranch)
64239313Sdim    : Id(Id), PickTrueBranch(PickTrueBranch) {}
65239313Sdim
66239313Sdimvoid ReplaceIfStmtWithItsBody::run(
67239313Sdim    const ast_matchers::MatchFinder::MatchResult &Result) {
68239313Sdim  if (const IfStmt *Node = Result.Nodes.getStmtAs<IfStmt>(Id)) {
69239313Sdim    const Stmt *Body = PickTrueBranch ? Node->getThen() : Node->getElse();
70239313Sdim    if (Body) {
71239313Sdim      Replace.insert(replaceStmtWithStmt(*Result.SourceManager, *Node, *Body));
72239313Sdim    } else if (!PickTrueBranch) {
73239313Sdim      // If we want to use the 'else'-branch, but it doesn't exist, delete
74239313Sdim      // the whole 'if'.
75239313Sdim      Replace.insert(replaceStmtWithText(*Result.SourceManager, *Node, ""));
76239313Sdim    }
77239313Sdim  }
78239313Sdim}
79239313Sdim
80239313Sdim} // end namespace tooling
81239313Sdim} // end namespace clang
82