Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 1
//===--- RefactoringCallbacks.h - Structural query framework ----*- C++ -*-===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
//  Provides callbacks to make common kinds of refactorings easy.
10
//
11
//  The general idea is to construct a matcher expression that describes a
12
//  subtree match on the AST and then replace the corresponding source code
13
//  either by some specific text or some other AST node.
14
//
15
//  Example:
16
//  int main(int argc, char **argv) {
17
//    ClangTool Tool(argc, argv);
18
//    MatchFinder Finder;
19
//    ReplaceStmtWithText Callback("integer", "42");
20
//    Finder.AddMatcher(id("integer", expression(integerLiteral())), Callback);
21
//    return Tool.run(newFrontendActionFactory(&Finder));
22
//  }
23
//
24
//  This will replace all integer literals with "42".
25
//
26
//===----------------------------------------------------------------------===//
27
 
28
#ifndef LLVM_CLANG_TOOLING_REFACTORINGCALLBACKS_H
29
#define LLVM_CLANG_TOOLING_REFACTORINGCALLBACKS_H
30
 
31
#include "clang/ASTMatchers/ASTMatchFinder.h"
32
#include "clang/Tooling/Refactoring.h"
33
 
34
namespace clang {
35
namespace tooling {
36
 
37
/// Base class for RefactoringCallbacks.
38
///
39
/// Collects \c tooling::Replacements while running.
40
class RefactoringCallback : public ast_matchers::MatchFinder::MatchCallback {
41
public:
42
  RefactoringCallback();
43
  Replacements &getReplacements();
44
 
45
protected:
46
  Replacements Replace;
47
};
48
 
49
/// Adaptor between \c ast_matchers::MatchFinder and \c
50
/// tooling::RefactoringTool.
51
///
52
/// Runs AST matchers and stores the \c tooling::Replacements in a map.
53
class ASTMatchRefactorer {
54
public:
55
  explicit ASTMatchRefactorer(
56
    std::map<std::string, Replacements> &FileToReplaces);
57
 
58
  template <typename T>
59
  void addMatcher(const T &Matcher, RefactoringCallback *Callback) {
60
    MatchFinder.addMatcher(Matcher, Callback);
61
    Callbacks.push_back(Callback);
62
  }
63
 
64
  void addDynamicMatcher(const ast_matchers::internal::DynTypedMatcher &Matcher,
65
                         RefactoringCallback *Callback);
66
 
67
  std::unique_ptr<ASTConsumer> newASTConsumer();
68
 
69
private:
70
  friend class RefactoringASTConsumer;
71
  std::vector<RefactoringCallback *> Callbacks;
72
  ast_matchers::MatchFinder MatchFinder;
73
  std::map<std::string, Replacements> &FileToReplaces;
74
};
75
 
76
/// Replace the text of the statement bound to \c FromId with the text in
77
/// \c ToText.
78
class ReplaceStmtWithText : public RefactoringCallback {
79
public:
80
  ReplaceStmtWithText(StringRef FromId, StringRef ToText);
81
  void run(const ast_matchers::MatchFinder::MatchResult &Result) override;
82
 
83
private:
84
  std::string FromId;
85
  std::string ToText;
86
};
87
 
88
/// Replace the text of an AST node bound to \c FromId with the result of
89
/// evaluating the template in \c ToTemplate.
90
///
91
/// Expressions of the form ${NodeName} in \c ToTemplate will be
92
/// replaced by the text of the node bound to ${NodeName}. The string
93
/// "$$" will be replaced by "$".
94
class ReplaceNodeWithTemplate : public RefactoringCallback {
95
public:
96
  static llvm::Expected<std::unique_ptr<ReplaceNodeWithTemplate>>
97
  create(StringRef FromId, StringRef ToTemplate);
98
  void run(const ast_matchers::MatchFinder::MatchResult &Result) override;
99
 
100
private:
101
  struct TemplateElement {
102
    enum { Literal, Identifier } Type;
103
    std::string Value;
104
  };
105
  ReplaceNodeWithTemplate(llvm::StringRef FromId,
106
                          std::vector<TemplateElement> Template);
107
  std::string FromId;
108
  std::vector<TemplateElement> Template;
109
};
110
 
111
/// Replace the text of the statement bound to \c FromId with the text of
112
/// the statement bound to \c ToId.
113
class ReplaceStmtWithStmt : public RefactoringCallback {
114
public:
115
  ReplaceStmtWithStmt(StringRef FromId, StringRef ToId);
116
  void run(const ast_matchers::MatchFinder::MatchResult &Result) override;
117
 
118
private:
119
  std::string FromId;
120
  std::string ToId;
121
};
122
 
123
/// Replace an if-statement bound to \c Id with the outdented text of its
124
/// body, choosing the consequent or the alternative based on whether
125
/// \c PickTrueBranch is true.
126
class ReplaceIfStmtWithItsBody : public RefactoringCallback {
127
public:
128
  ReplaceIfStmtWithItsBody(StringRef Id, bool PickTrueBranch);
129
  void run(const ast_matchers::MatchFinder::MatchResult &Result) override;
130
 
131
private:
132
  std::string Id;
133
  const bool PickTrueBranch;
134
};
135
 
136
} // end namespace tooling
137
} // end namespace clang
138
 
139
#endif