Skip to content

Commit da69dc5

Browse files
committed
[Refactoring] Move MoveMembersToExtension to a separate file
1 parent 514d20a commit da69dc5

File tree

3 files changed

+90
-76
lines changed

3 files changed

+90
-76
lines changed

Diff for: lib/Refactoring/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
add_swift_host_library(swiftRefactoring STATIC
22
CollapseNestedIfStmt.cpp
33
ConvertStringConcatenationToInterpolation.cpp
4+
MoveMembersToExtension.cpp
45
Refactoring.cpp
56
ReplaceBodiesWithFatalError.cpp
67
)

Diff for: lib/Refactoring/MoveMembersToExtension.cpp

+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2023 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+
15+
using namespace swift::refactoring;
16+
17+
bool RefactoringActionMoveMembersToExtension::isApplicable(
18+
const ResolvedRangeInfo &Info, DiagnosticEngine &Diag) {
19+
switch (Info.Kind) {
20+
case RangeKind::SingleDecl:
21+
case RangeKind::MultiTypeMemberDecl: {
22+
DeclContext *DC = Info.RangeContext;
23+
24+
// The the common decl context is not a nomial type, we cannot create an
25+
// extension for it
26+
if (!DC || !DC->getInnermostDeclarationDeclContext() ||
27+
!isa<NominalTypeDecl>(DC->getInnermostDeclarationDeclContext()))
28+
return false;
29+
30+
// Members of types not declared at top file level cannot be extracted
31+
// to an extension at top file level
32+
if (DC->getParent()->getContextKind() != DeclContextKind::FileUnit)
33+
return false;
34+
35+
// Check if contained nodes are all allowed decls.
36+
for (auto Node : Info.ContainedNodes) {
37+
Decl *D = Node.dyn_cast<Decl *>();
38+
if (!D)
39+
return false;
40+
41+
if (isa<AccessorDecl>(D) || isa<DestructorDecl>(D) ||
42+
isa<EnumCaseDecl>(D) || isa<EnumElementDecl>(D))
43+
return false;
44+
}
45+
46+
// We should not move instance variables with storage into the extension
47+
// because they are not allowed to be declared there
48+
for (auto DD : Info.DeclaredDecls) {
49+
if (auto ASD = dyn_cast<AbstractStorageDecl>(DD.VD)) {
50+
// Only disallow storages in the common decl context, allow them in
51+
// any subtypes
52+
if (ASD->hasStorage() && ASD->getDeclContext() == DC) {
53+
return false;
54+
}
55+
}
56+
}
57+
58+
return true;
59+
}
60+
case RangeKind::SingleExpression:
61+
case RangeKind::PartOfExpression:
62+
case RangeKind::SingleStatement:
63+
case RangeKind::MultiStatement:
64+
case RangeKind::Invalid:
65+
return false;
66+
}
67+
llvm_unreachable("unhandled kind");
68+
}
69+
70+
bool RefactoringActionMoveMembersToExtension::performChange() {
71+
DeclContext *DC = RangeInfo.RangeContext;
72+
73+
auto CommonTypeDecl =
74+
dyn_cast<NominalTypeDecl>(DC->getInnermostDeclarationDeclContext());
75+
assert(CommonTypeDecl && "Not applicable if common parent is no nomial type");
76+
77+
SmallString<64> Buffer;
78+
llvm::raw_svector_ostream OS(Buffer);
79+
OS << "\n\n";
80+
OS << "extension " << CommonTypeDecl->getName() << " {\n";
81+
OS << RangeInfo.ContentRange.str().trim();
82+
OS << "\n}";
83+
84+
// Insert extension after the type declaration
85+
EditConsumer.insertAfter(SM, CommonTypeDecl->getEndLoc(), Buffer);
86+
EditConsumer.remove(SM, RangeInfo.ContentRange);
87+
88+
return false;
89+
}

Diff for: lib/Refactoring/Refactoring.cpp

-76
Original file line numberDiff line numberDiff line change
@@ -1698,82 +1698,6 @@ bool RefactoringActionExtractRepeatedExpr::performChange() {
16981698
EditConsumer).performChange();
16991699
}
17001700

1701-
1702-
bool RefactoringActionMoveMembersToExtension::isApplicable(
1703-
const ResolvedRangeInfo &Info, DiagnosticEngine &Diag) {
1704-
switch (Info.Kind) {
1705-
case RangeKind::SingleDecl:
1706-
case RangeKind::MultiTypeMemberDecl: {
1707-
DeclContext *DC = Info.RangeContext;
1708-
1709-
// The the common decl context is not a nomial type, we cannot create an
1710-
// extension for it
1711-
if (!DC || !DC->getInnermostDeclarationDeclContext() ||
1712-
!isa<NominalTypeDecl>(DC->getInnermostDeclarationDeclContext()))
1713-
return false;
1714-
1715-
1716-
// Members of types not declared at top file level cannot be extracted
1717-
// to an extension at top file level
1718-
if (DC->getParent()->getContextKind() != DeclContextKind::FileUnit)
1719-
return false;
1720-
1721-
// Check if contained nodes are all allowed decls.
1722-
for (auto Node : Info.ContainedNodes) {
1723-
Decl *D = Node.dyn_cast<Decl*>();
1724-
if (!D)
1725-
return false;
1726-
1727-
if (isa<AccessorDecl>(D) || isa<DestructorDecl>(D) ||
1728-
isa<EnumCaseDecl>(D) || isa<EnumElementDecl>(D))
1729-
return false;
1730-
}
1731-
1732-
// We should not move instance variables with storage into the extension
1733-
// because they are not allowed to be declared there
1734-
for (auto DD : Info.DeclaredDecls) {
1735-
if (auto ASD = dyn_cast<AbstractStorageDecl>(DD.VD)) {
1736-
// Only disallow storages in the common decl context, allow them in
1737-
// any subtypes
1738-
if (ASD->hasStorage() && ASD->getDeclContext() == DC) {
1739-
return false;
1740-
}
1741-
}
1742-
}
1743-
1744-
return true;
1745-
}
1746-
case RangeKind::SingleExpression:
1747-
case RangeKind::PartOfExpression:
1748-
case RangeKind::SingleStatement:
1749-
case RangeKind::MultiStatement:
1750-
case RangeKind::Invalid:
1751-
return false;
1752-
}
1753-
llvm_unreachable("unhandled kind");
1754-
}
1755-
1756-
bool RefactoringActionMoveMembersToExtension::performChange() {
1757-
DeclContext *DC = RangeInfo.RangeContext;
1758-
1759-
auto CommonTypeDecl =
1760-
dyn_cast<NominalTypeDecl>(DC->getInnermostDeclarationDeclContext());
1761-
assert(CommonTypeDecl && "Not applicable if common parent is no nomial type");
1762-
1763-
SmallString<64> Buffer;
1764-
llvm::raw_svector_ostream OS(Buffer);
1765-
OS << "\n\n";
1766-
OS << "extension " << CommonTypeDecl->getName() << " {\n";
1767-
OS << RangeInfo.ContentRange.str().trim();
1768-
OS << "\n}";
1769-
1770-
// Insert extension after the type declaration
1771-
EditConsumer.insertAfter(SM, CommonTypeDecl->getEndLoc(), Buffer);
1772-
EditConsumer.remove(SM, RangeInfo.ContentRange);
1773-
1774-
return false;
1775-
}
1776-
17771701
/// Abstract helper class containing info about a TernaryExpr
17781702
/// that can be expanded into an IfStmt.
17791703
class ExpandableTernaryExprInfo {

0 commit comments

Comments
 (0)