12 #include "clang/AST/ASTContext.h"
13 #include "clang/AST/RecursiveASTVisitor.h"
14 #include "clang/AST/Stmt.h"
15 #include "clang/Basic/LangOptions.h"
16 #include "clang/Basic/SourceLocation.h"
17 #include "clang/Basic/SourceManager.h"
18 #include "clang/Lex/Lexer.h"
19 #include "clang/Tooling/Core/Replacement.h"
20 #include "llvm/ADT/None.h"
21 #include "llvm/ADT/Optional.h"
22 #include "llvm/ADT/StringRef.h"
23 #include "llvm/Support/Casting.h"
24 #include "llvm/Support/Error.h"
35 class SwapIfBranches :
public Tweak {
37 const char *id() const override final;
39 bool prepare(const Selection &
Inputs) override;
41 std::
string title()
const override {
return "Swap if branches"; }
42 Intent intent()
const override {
return Refactor; }
45 const IfStmt *If =
nullptr;
50 bool SwapIfBranches::prepare(
const Selection &
Inputs) {
51 for (
const SelectionTree::Node *N =
Inputs.ASTSelection.commonAncestor();
52 N && !If; N = N->Parent) {
54 if (dyn_cast_or_null<CompoundStmt>(N->ASTNode.get<Stmt>()))
56 If = dyn_cast_or_null<IfStmt>(N->ASTNode.get<Stmt>());
60 return If && dyn_cast_or_null<CompoundStmt>(If->getThen()) &&
61 dyn_cast_or_null<CompoundStmt>(If->getElse());
64 Expected<Tweak::Effect> SwapIfBranches::apply(
const Selection &
Inputs) {
66 auto &SrcMgr =
Inputs.AST->getSourceManager();
69 If->getThen()->getSourceRange());
71 return llvm::createStringError(
72 llvm::inconvertibleErrorCode(),
73 "Could not obtain range of the 'then' branch. Macros?");
75 If->getElse()->getSourceRange());
77 return llvm::createStringError(
78 llvm::inconvertibleErrorCode(),
79 "Could not obtain range of the 'else' branch. Macros?");
84 tooling::Replacements Result;
85 if (
auto Err = Result.add(tooling::Replacement(
Ctx.getSourceManager(),
87 ThenCode.size(), ElseCode)))
88 return std::move(Err);
89 if (
auto Err = Result.add(tooling::Replacement(
Ctx.getSourceManager(),
91 ElseCode.size(), ThenCode)))
92 return std::move(Err);
93 return Effect::mainFileEdit(SrcMgr, std::move(Result));