Skip to content

Commit f4bcf55

Browse files
author
IgnatSergeev
committed
Add refactoring actions
Added redundand-if, redundand-while, unused-method, unused-field, simplify-expr refactoring actions
1 parent 240cffa commit f4bcf55

File tree

1 file changed

+145
-0
lines changed

1 file changed

+145
-0
lines changed

clang/lib/Tooling/Refactoring/RefactoringActions.cpp

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,22 @@
66
//
77
//===----------------------------------------------------------------------===//
88

9+
#include "clang/ASTMatchers/ASTMatchers.h"
10+
#include "clang/ASTMatchers/ASTMatchersMacros.h"
11+
#include "clang/Tooling/Refactoring/Edit/EditMatchRule.h"
912
#include "clang/Tooling/Refactoring/Extract/Extract.h"
1013
#include "clang/Tooling/Refactoring/RefactoringAction.h"
1114
#include "clang/Tooling/Refactoring/RefactoringOptions.h"
1215
#include "clang/Tooling/Refactoring/Rename/RenamingAction.h"
16+
#include "clang/Tooling/Transformer/RewriteRule.h"
17+
#include "clang/Tooling/Transformer/Stencil.h"
1318

1419
namespace clang {
1520
namespace tooling {
1621

22+
using namespace transformer;
23+
using namespace ast_matchers;
24+
1725
namespace {
1826

1927
class DeclNameOption final : public OptionalRefactoringOption<std::string> {
@@ -93,13 +101,150 @@ class LocalRename final : public RefactoringAction {
93101
}
94102
};
95103

104+
class RedundandIf final : public RefactoringAction {
105+
public:
106+
StringRef getCommand() const override { return "redundand-if"; }
107+
108+
StringRef getDescription() const override {
109+
return "Transforms if statement around given location with always true or "
110+
"false condition";
111+
}
112+
113+
/// Returns a set of refactoring actions rules that are defined by this
114+
/// action.
115+
RefactoringActionRules createActionRules() const override {
116+
RefactoringActionRules Rules;
117+
Rules.push_back(createRefactoringActionRule<EditMatchRule>(
118+
ASTLocMatchRequirement<StatementMatcher>(ifStmt(
119+
allOf(anyOf(hasCondition(cxxBoolLiteral(equals(true)).bind("true")),
120+
hasCondition(cxxBoolLiteral(equals(false)))),
121+
optionally(hasThen(stmt().bind("then"))),
122+
optionally(hasElse(stmt().bind("else")))))),
123+
EditGeneratorRequirement(ifBound(
124+
"true", ifBound("then", changeTo(cat(node("then")))),
125+
ifBound("else", changeTo(cat(node("else"))), changeTo(cat("")))))));
126+
127+
return Rules;
128+
}
129+
};
130+
131+
class RedundandWhile final : public RefactoringAction {
132+
public:
133+
StringRef getCommand() const override { return "redundand-while"; }
134+
135+
StringRef getDescription() const override {
136+
return "Removes while statement around given location with always false "
137+
"condition";
138+
}
139+
140+
/// Returns a set of refactoring actions rules that are defined by this
141+
/// action.
142+
RefactoringActionRules createActionRules() const override {
143+
RefactoringActionRules Rules;
144+
Rules.push_back(createRefactoringActionRule<EditMatchRule>(
145+
ASTLocMatchRequirement<StatementMatcher>(
146+
whileStmt(hasCondition(cxxBoolLiteral(equals(false))))),
147+
EditGeneratorRequirement(edit(changeTo(cat(""))))));
148+
149+
return Rules;
150+
}
151+
};
152+
153+
AST_MATCHER(Decl, isReferenced) { return Node.isReferenced(); }
154+
155+
class UnusedField final : public RefactoringAction {
156+
public:
157+
StringRef getCommand() const override { return "unused-field"; }
158+
159+
StringRef getDescription() const override {
160+
return "Removes unused field of a class around given location";
161+
}
162+
163+
/// Returns a set of refactoring actions rules that are defined by this
164+
/// action.
165+
RefactoringActionRules createActionRules() const override {
166+
RefactoringActionRules Rules;
167+
Rules.push_back(createRefactoringActionRule<EditMatchRule>(
168+
ASTLocMatchRequirement<DeclarationMatcher>(
169+
fieldDecl(unless(isReferenced()),
170+
unless(hasAttr(attr::Kind::Unused)))
171+
.bind("field")),
172+
EditGeneratorRequirement(edit(changeTo(node("field"), cat(""))))));
173+
174+
return Rules;
175+
}
176+
};
177+
178+
class UnusedMethod final : public RefactoringAction {
179+
public:
180+
StringRef getCommand() const override { return "unused-method"; }
181+
182+
StringRef getDescription() const override {
183+
return "Removes unused method of a class around given location";
184+
}
185+
186+
/// Returns a set of refactoring actions rules that are defined by this
187+
/// action.
188+
RefactoringActionRules createActionRules() const override {
189+
RefactoringActionRules Rules;
190+
Rules.push_back(createRefactoringActionRule<EditMatchRule>(
191+
ASTLocMatchRequirement<DeclarationMatcher>(
192+
cxxMethodDecl(unless(isReferenced()),
193+
unless(hasAttr(attr::Kind::Unused)))
194+
.bind("method")),
195+
EditGeneratorRequirement(edit(changeTo(node("method"), cat(""))))));
196+
197+
return Rules;
198+
}
199+
};
200+
201+
class SimplifyExpr final : public RefactoringAction {
202+
public:
203+
StringRef getCommand() const override { return "simplify-expr"; }
204+
205+
StringRef getDescription() const override {
206+
return "Simplifies expr around given location";
207+
}
208+
209+
/// Returns a set of refactoring actions rules that are defined by this
210+
/// action.
211+
RefactoringActionRules createActionRules() const override {
212+
RefactoringActionRules Rules;
213+
Rules.push_back(createRefactoringActionRule<EditMatchRule>(
214+
ASTLocMatchRequirement<StatementMatcher>(anyOf(
215+
binaryOperator(
216+
hasOperatorName("&&"), hasRHS(expr().bind("rhs")),
217+
hasLHS(expr().bind("lhs")),
218+
anyOf(hasRHS(cxxBoolLiteral(equals(false)).bind("save-rhs")),
219+
hasLHS(cxxBoolLiteral(equals(false))),
220+
hasRHS(cxxBoolLiteral(equals(true))),
221+
hasLHS(cxxBoolLiteral(equals(true)).bind("save-rhs")))),
222+
binaryOperator(
223+
hasOperatorName("||"), hasRHS(expr().bind("rhs")),
224+
hasLHS(expr().bind("lhs")),
225+
anyOf(hasRHS(cxxBoolLiteral(equals(false))),
226+
hasLHS(cxxBoolLiteral(equals(false)).bind("save-rhs")),
227+
hasRHS(cxxBoolLiteral(equals(true)).bind("save-rhs")),
228+
hasLHS(cxxBoolLiteral(equals(true))))))),
229+
EditGeneratorRequirement(ifBound("save-rhs", changeTo(cat(node("rhs"))),
230+
changeTo(cat(node("lhs")))))));
231+
232+
return Rules;
233+
}
234+
};
235+
96236
} // end anonymous namespace
97237

98238
std::vector<std::unique_ptr<RefactoringAction>> createRefactoringActions() {
99239
std::vector<std::unique_ptr<RefactoringAction>> Actions;
100240

101241
Actions.push_back(std::make_unique<LocalRename>());
102242
Actions.push_back(std::make_unique<ExtractRefactoring>());
243+
Actions.push_back(std::make_unique<RedundandIf>());
244+
Actions.push_back(std::make_unique<RedundandWhile>());
245+
Actions.push_back(std::make_unique<UnusedField>());
246+
Actions.push_back(std::make_unique<UnusedMethod>());
247+
Actions.push_back(std::make_unique<SimplifyExpr>());
103248

104249
return Actions;
105250
}

0 commit comments

Comments
 (0)