mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[Refactoring] Simplify implementation of "move members to extension" action
This commit is contained in:
@@ -296,23 +296,6 @@ DeclContext *DeclContext::getParentForLookup() const {
|
|||||||
return getParent();
|
return getParent();
|
||||||
}
|
}
|
||||||
|
|
||||||
DeclContext *DeclContext::getCommonParentContext(DeclContext *A,
|
|
||||||
DeclContext *B) {
|
|
||||||
if (A == B)
|
|
||||||
return A;
|
|
||||||
|
|
||||||
if (A->isChildContextOf(B))
|
|
||||||
return B;
|
|
||||||
|
|
||||||
// Peel away layers of A until we reach a common parent
|
|
||||||
for (DeclContext *CurDC = A; CurDC; CurDC = CurDC->getParent()) {
|
|
||||||
if (B->isChildContextOf(CurDC))
|
|
||||||
return CurDC;
|
|
||||||
}
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
ModuleDecl *DeclContext::getParentModule() const {
|
ModuleDecl *DeclContext::getParentModule() const {
|
||||||
const DeclContext *DC = this;
|
const DeclContext *DC = this;
|
||||||
while (!DC->isModuleContext())
|
while (!DC->isModuleContext())
|
||||||
|
|||||||
@@ -1521,36 +1521,24 @@ bool RefactoringActionExtractRepeatedExpr::performChange() {
|
|||||||
EditConsumer).performChange();
|
EditConsumer).performChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute a decl context that is the parent context for all decls in
|
|
||||||
// \c DeclaredDecls. Return \c nullptr if no such context exists.
|
|
||||||
DeclContext *getCommonDeclContext(ArrayRef<DeclaredDecl> DeclaredDecls) {
|
|
||||||
if (DeclaredDecls.empty())
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
DeclContext *CommonDC = DeclaredDecls.front().VD->getDeclContext();
|
|
||||||
for (auto DD : DeclaredDecls) {
|
|
||||||
auto OtherDC = DD.VD->getDeclContext();
|
|
||||||
CommonDC = DeclContext::getCommonParentContext(CommonDC, OtherDC);
|
|
||||||
}
|
|
||||||
return CommonDC;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RefactoringActionMoveMembersToExtension::isApplicable(
|
bool RefactoringActionMoveMembersToExtension::isApplicable(
|
||||||
ResolvedRangeInfo Info, DiagnosticEngine &Diag) {
|
ResolvedRangeInfo Info, DiagnosticEngine &Diag) {
|
||||||
switch (Info.Kind) {
|
switch (Info.Kind) {
|
||||||
case RangeKind::SingleDecl:
|
case RangeKind::SingleDecl:
|
||||||
case RangeKind::MultiTypeMemberDecl: {
|
case RangeKind::MultiTypeMemberDecl: {
|
||||||
DeclContext *CommonDC = getCommonDeclContext(Info.DeclaredDecls);
|
DeclContext *DC = Info.RangeContext;
|
||||||
|
|
||||||
// The the common decl context is not a nomial type, we cannot create an
|
// The the common decl context is not a nomial type, we cannot create an
|
||||||
// extension for it
|
// extension for it
|
||||||
if (!CommonDC || !CommonDC->getInnermostDeclarationDeclContext() ||
|
if (!DC || !DC->getInnermostDeclarationDeclContext() ||
|
||||||
!isa<NominalTypeDecl>(CommonDC->getInnermostDeclarationDeclContext()))
|
!isa<NominalTypeDecl>(DC->getInnermostDeclarationDeclContext()))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
||||||
// Members of types not declared at top file level cannot be extracted
|
// Members of types not declared at top file level cannot be extracted
|
||||||
// to an extension at top file level
|
// to an extension at top file level
|
||||||
if (CommonDC->getParent()->getContextKind() != DeclContextKind::FileUnit)
|
if (DC->getParent()->getContextKind() != DeclContextKind::FileUnit)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Check if contained nodes are all allowed decls.
|
// Check if contained nodes are all allowed decls.
|
||||||
@@ -1570,7 +1558,7 @@ bool RefactoringActionMoveMembersToExtension::isApplicable(
|
|||||||
if (auto ASD = dyn_cast<AbstractStorageDecl>(DD.VD)) {
|
if (auto ASD = dyn_cast<AbstractStorageDecl>(DD.VD)) {
|
||||||
// Only disallow storages in the common decl context, allow them in
|
// Only disallow storages in the common decl context, allow them in
|
||||||
// any subtypes
|
// any subtypes
|
||||||
if (ASD->hasStorage() && ASD->getDeclContext() == CommonDC) {
|
if (ASD->hasStorage() && ASD->getDeclContext() == DC) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1588,10 +1576,10 @@ bool RefactoringActionMoveMembersToExtension::isApplicable(
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool RefactoringActionMoveMembersToExtension::performChange() {
|
bool RefactoringActionMoveMembersToExtension::performChange() {
|
||||||
DeclContext *CommonDC = getCommonDeclContext(RangeInfo.DeclaredDecls);
|
DeclContext *DC = RangeInfo.RangeContext;
|
||||||
|
|
||||||
auto CommonTypeDecl =
|
auto CommonTypeDecl =
|
||||||
dyn_cast<NominalTypeDecl>(CommonDC->getInnermostDeclarationDeclContext());
|
dyn_cast<NominalTypeDecl>(DC->getInnermostDeclarationDeclContext());
|
||||||
assert(CommonTypeDecl && "Not applicable if common parent is no nomial type");
|
assert(CommonTypeDecl && "Not applicable if common parent is no nomial type");
|
||||||
|
|
||||||
SmallString<64> Buffer;
|
SmallString<64> Buffer;
|
||||||
|
|||||||
Reference in New Issue
Block a user