[Refactoring] Simplify implementation of "move members to extension" action

This commit is contained in:
Rintaro Ishizaki
2018-05-25 18:38:34 +09:00
parent db3020f031
commit 3c367e9227
2 changed files with 8 additions and 37 deletions

View File

@@ -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())

View File

@@ -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;