Skip to content

Commit ec71836

Browse files
committed
[Refactoring] Extract CollapseNestedIfStmt to its own file
1 parent 6b2e54d commit ec71836

File tree

3 files changed

+85
-68
lines changed

3 files changed

+85
-68
lines changed

lib/Refactoring/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
add_swift_host_library(swiftRefactoring STATIC
2+
CollapseNestedIfStmt.cpp
23
ConvertStringConcatenationToInterpolation.cpp
34
Refactoring.cpp
45
)
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#include "RefactoringActions.h"
14+
#include "swift/AST/Stmt.h"
15+
16+
using namespace swift::refactoring;
17+
18+
static std::pair<IfStmt *, IfStmt *>
19+
findCollapseNestedIfTarget(ResolvedCursorInfoPtr CursorInfo) {
20+
auto StmtStartInfo = dyn_cast<ResolvedStmtStartCursorInfo>(CursorInfo);
21+
if (!StmtStartInfo)
22+
return {};
23+
24+
// Ensure the statement is 'if' statement. It must not have 'else' clause.
25+
IfStmt *OuterIf = dyn_cast<IfStmt>(StmtStartInfo->getTrailingStmt());
26+
if (!OuterIf)
27+
return {};
28+
if (OuterIf->getElseStmt())
29+
return {};
30+
31+
// The body must contain a sole inner 'if' statement.
32+
auto Body = dyn_cast_or_null<BraceStmt>(OuterIf->getThenStmt());
33+
if (!Body || Body->getNumElements() != 1)
34+
return {};
35+
36+
IfStmt *InnerIf =
37+
dyn_cast_or_null<IfStmt>(Body->getFirstElement().dyn_cast<Stmt *>());
38+
if (!InnerIf)
39+
return {};
40+
41+
// Inner 'if' statement also cannot have 'else' clause.
42+
if (InnerIf->getElseStmt())
43+
return {};
44+
45+
return {OuterIf, InnerIf};
46+
}
47+
48+
bool RefactoringActionCollapseNestedIfStmt::isApplicable(
49+
ResolvedCursorInfoPtr CursorInfo, DiagnosticEngine &Diag) {
50+
return findCollapseNestedIfTarget(CursorInfo).first;
51+
}
52+
53+
bool RefactoringActionCollapseNestedIfStmt::performChange() {
54+
auto Target = findCollapseNestedIfTarget(CursorInfo);
55+
if (!Target.first)
56+
return true;
57+
auto OuterIf = Target.first;
58+
auto InnerIf = Target.second;
59+
60+
EditorConsumerInsertStream OS(
61+
EditConsumer, SM,
62+
Lexer::getCharSourceRangeFromSourceRange(SM, OuterIf->getSourceRange()));
63+
64+
OS << tok::kw_if << " ";
65+
66+
// Emit conditions.
67+
bool first = true;
68+
for (auto &C : llvm::concat<StmtConditionElement>(OuterIf->getCond(),
69+
InnerIf->getCond())) {
70+
if (first)
71+
first = false;
72+
else
73+
OS << ", ";
74+
OS << Lexer::getCharSourceRangeFromSourceRange(SM, C.getSourceRange())
75+
.str();
76+
}
77+
78+
// Emit body.
79+
OS << " ";
80+
OS << Lexer::getCharSourceRangeFromSourceRange(
81+
SM, InnerIf->getThenStmt()->getSourceRange())
82+
.str();
83+
return false;
84+
}

lib/Refactoring/Refactoring.cpp

Lines changed: 0 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1846,74 +1846,6 @@ bool RefactoringActionReplaceBodiesWithFatalError::performChange() {
18461846
return false;
18471847
}
18481848

1849-
static std::pair<IfStmt *, IfStmt *>
1850-
findCollapseNestedIfTarget(ResolvedCursorInfoPtr CursorInfo) {
1851-
auto StmtStartInfo = dyn_cast<ResolvedStmtStartCursorInfo>(CursorInfo);
1852-
if (!StmtStartInfo)
1853-
return {};
1854-
1855-
// Ensure the statement is 'if' statement. It must not have 'else' clause.
1856-
IfStmt *OuterIf = dyn_cast<IfStmt>(StmtStartInfo->getTrailingStmt());
1857-
if (!OuterIf)
1858-
return {};
1859-
if (OuterIf->getElseStmt())
1860-
return {};
1861-
1862-
// The body must contain a sole inner 'if' statement.
1863-
auto Body = dyn_cast_or_null<BraceStmt>(OuterIf->getThenStmt());
1864-
if (!Body || Body->getNumElements() != 1)
1865-
return {};
1866-
1867-
IfStmt *InnerIf =
1868-
dyn_cast_or_null<IfStmt>(Body->getFirstElement().dyn_cast<Stmt *>());
1869-
if (!InnerIf)
1870-
return {};
1871-
1872-
// Inner 'if' statement also cannot have 'else' clause.
1873-
if (InnerIf->getElseStmt())
1874-
return {};
1875-
1876-
return {OuterIf, InnerIf};
1877-
}
1878-
1879-
bool RefactoringActionCollapseNestedIfStmt::isApplicable(
1880-
ResolvedCursorInfoPtr CursorInfo, DiagnosticEngine &Diag) {
1881-
return findCollapseNestedIfTarget(CursorInfo).first;
1882-
}
1883-
1884-
bool RefactoringActionCollapseNestedIfStmt::performChange() {
1885-
auto Target = findCollapseNestedIfTarget(CursorInfo);
1886-
if (!Target.first)
1887-
return true;
1888-
auto OuterIf = Target.first;
1889-
auto InnerIf = Target.second;
1890-
1891-
EditorConsumerInsertStream OS(
1892-
EditConsumer, SM,
1893-
Lexer::getCharSourceRangeFromSourceRange(SM, OuterIf->getSourceRange()));
1894-
1895-
OS << tok::kw_if << " ";
1896-
1897-
// Emit conditions.
1898-
bool first = true;
1899-
for (auto &C : llvm::concat<StmtConditionElement>(OuterIf->getCond(),
1900-
InnerIf->getCond())) {
1901-
if (first)
1902-
first = false;
1903-
else
1904-
OS << ", ";
1905-
OS << Lexer::getCharSourceRangeFromSourceRange(SM, C.getSourceRange())
1906-
.str();
1907-
}
1908-
1909-
// Emit body.
1910-
OS << " ";
1911-
OS << Lexer::getCharSourceRangeFromSourceRange(
1912-
SM, InnerIf->getThenStmt()->getSourceRange())
1913-
.str();
1914-
return false;
1915-
}
1916-
19171849
/// Abstract helper class containing info about a TernaryExpr
19181850
/// that can be expanded into an IfStmt.
19191851
class ExpandableTernaryExprInfo {

0 commit comments

Comments
 (0)