Delete/Move: Delete entire file when deleting top-level class or object and no other top-level declarations are present. Ask the user confirmation if deletion if caused by the Move refactoring

#KT-8033 Fixed
This commit is contained in:
Alexey Sedunov
2015-06-15 16:17:57 +03:00
parent e1e818858e
commit dda271d38d
4 changed files with 23 additions and 16 deletions
@@ -16,10 +16,13 @@
package org.jetbrains.kotlin.psi
import com.intellij.lang.ASTNode
import com.intellij.lang.ASTNode
import com.intellij.navigation.ItemPresentation
import com.intellij.navigation.ItemPresentationProviders
import com.intellij.psi.PsiElement
import com.intellij.psi.impl.CheckUtil
import com.intellij.psi.impl.source.codeStyle.CodeEditUtil
import com.intellij.psi.stubs.IStubElementType
import org.jetbrains.kotlin.JetNodeTypes
import org.jetbrains.kotlin.lexer.JetTokens
@@ -62,4 +65,16 @@ abstract public class JetClassOrObject : JetTypeParameterListOwnerStub<KotlinCla
public fun getSecondaryConstructors(): List<JetSecondaryConstructor> = getBody()?.getSecondaryConstructors().orEmpty()
public fun isAnnotation(): Boolean = hasModifier(JetTokens.ANNOTATION_KEYWORD)
public override fun delete() {
CheckUtil.checkWritable(this);
val file = getContainingJetFile();
if (!isTopLevel() || file.getDeclarations().size() > 1) {
CodeEditUtil.removeChild(getParent().getNode(), getNode());
}
else {
file.delete();
}
}
}
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.idea.core
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiWhiteSpace
import com.intellij.psi.impl.source.codeStyle.CodeEditUtil
import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil
@@ -148,4 +149,8 @@ private fun deleteElementWithDelimiters(element: PsiElement) {
val parent = element.getParent()
parent.deleteChildRange(from, to)
}
public fun PsiElement.deleteSingle() {
CodeEditUtil.removeChild(getParent()?.getNode() ?: return, getNode() ?: return)
}
@@ -45,6 +45,7 @@ import org.jetbrains.kotlin.asJava.toLightElements
import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde
import org.jetbrains.kotlin.idea.codeInsight.JetFileReferencesResolver
import org.jetbrains.kotlin.idea.codeInsight.shorten.addToShorteningWaitSet
import org.jetbrains.kotlin.idea.core.deleteSingle
import org.jetbrains.kotlin.idea.core.refactoring.getUsageContext
import org.jetbrains.kotlin.idea.refactoring.JetRefactoringBundle
import org.jetbrains.kotlin.idea.refactoring.fqName.getKotlinFqName
@@ -68,7 +69,7 @@ trait Mover: (originalElement: JetNamedDeclaration, targetFile: JetFile) -> JetN
object Default: Mover {
override fun invoke(originalElement: JetNamedDeclaration, targetFile: JetFile): JetNamedDeclaration {
val newElement = targetFile.add(originalElement) as JetNamedDeclaration
originalElement.delete()
originalElement.deleteSingle()
return newElement
}
}
@@ -37,12 +37,12 @@ import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.idea.JetBundle
import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.core.deleteElementAndCleanParent
import org.jetbrains.kotlin.idea.refactoring.JetRefactoringUtil
import org.jetbrains.kotlin.idea.references.JetReference
import org.jetbrains.kotlin.idea.search.usagesSearch.processDelegationCallConstructorUsages
import org.jetbrains.kotlin.lexer.JetTokens
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.idea.core.deleteElementAndCleanParent
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
import org.jetbrains.kotlin.resolve.BindingContext
import java.util.ArrayList
@@ -326,18 +326,4 @@ public class KotlinSafeDeleteProcessor : JavaSafeDeleteProcessor() {
else -> super.getElementsToSearch(element, module, allElementsToDelete)
}
}
override fun getAdditionalElementsToDelete(
element: PsiElement,
allElementsToDelete: MutableCollection<PsiElement>,
askUser: Boolean
): Collection<PsiElement> {
val filesToDelete = allElementsToDelete
.filter { it is JetNamedDeclaration && it.getContainingJetFile() == it.getParent() }
.groupBy { (it as JetNamedDeclaration).getContainingJetFile() }
.filter { it.getKey().getDeclarations().size() == it.getValue().size() }
.keySet()
return super.getAdditionalElementsToDelete(element, allElementsToDelete, askUser)?.let { it + filesToDelete }
?: filesToDelete
}
}