Move: Suggest deleting file when all declarations are moved
This commit is contained in:
@@ -173,11 +173,6 @@ public class JetClass extends JetTypeParameterListOwnerStub<KotlinClassStub> imp
|
|||||||
return hasModifier(JetTokens.INNER_KEYWORD);
|
return hasModifier(JetTokens.INNER_KEYWORD);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void delete() throws IncorrectOperationException {
|
|
||||||
JetPsiUtil.deleteClass(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isEquivalentTo(PsiElement another) {
|
public boolean isEquivalentTo(PsiElement another) {
|
||||||
if (super.isEquivalentTo(another)) {
|
if (super.isEquivalentTo(another)) {
|
||||||
|
|||||||
@@ -182,11 +182,6 @@ public class JetObjectDeclaration extends JetNamedDeclarationStub<KotlinObjectSt
|
|||||||
return findChildByType(JetTokens.OBJECT_KEYWORD);
|
return findChildByType(JetTokens.OBJECT_KEYWORD);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void delete() throws IncorrectOperationException {
|
|
||||||
JetPsiUtil.deleteClass(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ItemPresentation getPresentation() {
|
public ItemPresentation getPresentation() {
|
||||||
return ItemPresentationProviders.getItemPresentation(this);
|
return ItemPresentationProviders.getItemPresentation(this);
|
||||||
|
|||||||
@@ -297,18 +297,6 @@ public class JetPsiUtil {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void deleteClass(@NotNull JetClassOrObject clazz) {
|
|
||||||
CheckUtil.checkWritable(clazz);
|
|
||||||
JetFile file = clazz.getContainingJetFile();
|
|
||||||
if (!clazz.isTopLevel() || file.getDeclarations().size() > 1) {
|
|
||||||
PsiElement parent = clazz.getParent();
|
|
||||||
CodeEditUtil.removeChild(parent.getNode(), clazz.getNode());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
file.delete();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public static Name getAliasName(@NotNull JetImportDirective importDirective) {
|
public static Name getAliasName(@NotNull JetImportDirective importDirective) {
|
||||||
String aliasName = importDirective.getAliasName();
|
String aliasName = importDirective.getAliasName();
|
||||||
|
|||||||
+5
@@ -86,6 +86,7 @@ public class MoveKotlinTopLevelDeclarationsOptions(
|
|||||||
val searchInCommentsAndStrings: Boolean = true,
|
val searchInCommentsAndStrings: Boolean = true,
|
||||||
val searchInNonCode: Boolean = true,
|
val searchInNonCode: Boolean = true,
|
||||||
val updateInternalReferences: Boolean = true,
|
val updateInternalReferences: Boolean = true,
|
||||||
|
val deleteSourceFile: Boolean = false,
|
||||||
val moveCallback: MoveCallback? = null
|
val moveCallback: MoveCallback? = null
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -282,6 +283,10 @@ public class MoveKotlinTopLevelDeclarationsProcessor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (options.deleteSourceFile) {
|
||||||
|
options.sourceFile.delete()
|
||||||
|
}
|
||||||
|
|
||||||
nonCodeUsages = postProcessMoveUsages(usageList, oldToNewElementsMapping).toTypedArray()
|
nonCodeUsages = postProcessMoveUsages(usageList, oldToNewElementsMapping).toTypedArray()
|
||||||
}
|
}
|
||||||
catch (e: IncorrectOperationException) {
|
catch (e: IncorrectOperationException) {
|
||||||
|
|||||||
+65
-52
@@ -505,67 +505,80 @@ public class MoveKotlinTopLevelDeclarationsDialog extends RefactoringDialog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (isMoveToPackage() && elementsToMove.equals(sourceFile.getDeclarations())) {
|
boolean deleteSourceFile = false;
|
||||||
final MoveDestination moveDestination = selectPackageBasedMoveDestination();
|
|
||||||
//noinspection ConstantConditions
|
if (elementsToMove.size() == sourceFile.getDeclarations().size()) {
|
||||||
PsiDirectory targetDir = moveDestination.getTargetIfExists(sourceFile);
|
if (isMoveToPackage()) {
|
||||||
final String targetFileName = tfFileNameInPackage.getText();
|
final MoveDestination moveDestination = selectPackageBasedMoveDestination();
|
||||||
if (targetDir == null || targetDir.findFile(targetFileName) == null) {
|
|
||||||
//noinspection ConstantConditions
|
//noinspection ConstantConditions
|
||||||
final String temporaryName = UniqueNameGenerator.generateUniqueName(
|
PsiDirectory targetDir = moveDestination.getTargetIfExists(sourceFile);
|
||||||
"temp",
|
final String targetFileName = tfFileNameInPackage.getText();
|
||||||
"",
|
if (targetDir == null || targetDir.findFile(targetFileName) == null) {
|
||||||
".kt",
|
//noinspection ConstantConditions
|
||||||
KotlinPackage.map(
|
final String temporaryName = UniqueNameGenerator.generateUniqueName(
|
||||||
sourceFile.getContainingDirectory().getFiles(),
|
"temp",
|
||||||
new Function1<PsiFile, String>() {
|
"",
|
||||||
@Override
|
".kt",
|
||||||
public String invoke(PsiFile file) {
|
KotlinPackage.map(
|
||||||
return file.getName();
|
sourceFile.getContainingDirectory().getFiles(),
|
||||||
}
|
new Function1<PsiFile, String>() {
|
||||||
}
|
@Override
|
||||||
)
|
public String invoke(PsiFile file) {
|
||||||
);
|
return file.getName();
|
||||||
PsiDirectory targetDirectory = ApplicationPackage.runWriteAction(
|
|
||||||
new Function0<PsiDirectory>() {
|
|
||||||
@Override
|
|
||||||
public PsiDirectory invoke() {
|
|
||||||
sourceFile.setName(temporaryName);
|
|
||||||
return moveDestination.getTargetDirectory(sourceFile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
invokeRefactoring(
|
|
||||||
new MoveFilesOrDirectoriesProcessor(
|
|
||||||
myProject,
|
|
||||||
new PsiElement[] {sourceFile},
|
|
||||||
targetDirectory,
|
|
||||||
RefactoringSettings.getInstance().MOVE_SEARCH_FOR_REFERENCES_FOR_FILE,
|
|
||||||
isSearchInComments(),
|
|
||||||
isSearchInNonJavaFiles(),
|
|
||||||
new MoveCallback() {
|
|
||||||
@Override
|
|
||||||
public void refactoringCompleted() {
|
|
||||||
try {
|
|
||||||
sourceFile.setName(targetFileName);
|
|
||||||
}
|
}
|
||||||
finally {
|
}
|
||||||
if (moveCallback != null) {
|
)
|
||||||
moveCallback.refactoringCompleted();
|
);
|
||||||
|
PsiDirectory targetDirectory = ApplicationPackage.runWriteAction(
|
||||||
|
new Function0<PsiDirectory>() {
|
||||||
|
@Override
|
||||||
|
public PsiDirectory invoke() {
|
||||||
|
sourceFile.setName(temporaryName);
|
||||||
|
return moveDestination.getTargetDirectory(sourceFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
invokeRefactoring(
|
||||||
|
new MoveFilesOrDirectoriesProcessor(
|
||||||
|
myProject,
|
||||||
|
new PsiElement[] {sourceFile},
|
||||||
|
targetDirectory,
|
||||||
|
RefactoringSettings.getInstance().MOVE_SEARCH_FOR_REFERENCES_FOR_FILE,
|
||||||
|
isSearchInComments(),
|
||||||
|
isSearchInNonJavaFiles(),
|
||||||
|
new MoveCallback() {
|
||||||
|
@Override
|
||||||
|
public void refactoringCompleted() {
|
||||||
|
try {
|
||||||
|
sourceFile.setName(targetFileName);
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
if (moveCallback != null) {
|
||||||
|
moveCallback.refactoringCompleted();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
},
|
EmptyRunnable.INSTANCE
|
||||||
EmptyRunnable.INSTANCE
|
)
|
||||||
)
|
);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ret = Messages.showYesNoCancelDialog(
|
||||||
|
myProject,
|
||||||
|
"You are going to move all declarations out of '" + sourceFile.getVirtualFile().getPath() + "'. Do you want to delete this file?",
|
||||||
|
RefactoringBundle.message("move.title"),
|
||||||
|
Messages.getQuestionIcon()
|
||||||
);
|
);
|
||||||
|
if (ret == Messages.CANCEL) return;
|
||||||
return;
|
deleteSourceFile = ret == Messages.YES;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MoveKotlinTopLevelDeclarationsOptions options = new MoveKotlinTopLevelDeclarationsOptions(
|
MoveKotlinTopLevelDeclarationsOptions options = new MoveKotlinTopLevelDeclarationsOptions(
|
||||||
sourceFile, elementsToMove, target, isSearchInComments(), isSearchInNonJavaFiles(), true, moveCallback
|
sourceFile, elementsToMove, target, isSearchInComments(), isSearchInNonJavaFiles(), true, deleteSourceFile, moveCallback
|
||||||
);
|
);
|
||||||
invokeRefactoring(new MoveKotlinTopLevelDeclarationsProcessor(myProject, options, Mover.Default.INSTANCE$));
|
invokeRefactoring(new MoveKotlinTopLevelDeclarationsProcessor(myProject, options, Mover.Default.INSTANCE$));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -156,8 +156,10 @@ fun createMoveUsageInfoIfPossible(
|
|||||||
}
|
}
|
||||||
|
|
||||||
public fun guessNewFileName(sourceFile: JetFile, declarationsToMove: Collection<JetNamedDeclaration>): String? {
|
public fun guessNewFileName(sourceFile: JetFile, declarationsToMove: Collection<JetNamedDeclaration>): String? {
|
||||||
|
assert(sourceFile.getDeclarations().containsAll(declarationsToMove))
|
||||||
|
|
||||||
if (declarationsToMove.isEmpty()) return null
|
if (declarationsToMove.isEmpty()) return null
|
||||||
if (sourceFile.getDeclarations() == declarationsToMove) return sourceFile.getName()
|
if (sourceFile.getDeclarations().size() == declarationsToMove.size()) return sourceFile.getName()
|
||||||
|
|
||||||
val representative = declarationsToMove.firstOrNull { it is JetClassOrObject } ?: declarationsToMove.first()
|
val representative = declarationsToMove.firstOrNull { it is JetClassOrObject } ?: declarationsToMove.first()
|
||||||
return "${representative.getName()}.${JetFileType.EXTENSION}"
|
return "${representative.getName()}.${JetFileType.EXTENSION}"
|
||||||
|
|||||||
+26
-13
@@ -24,30 +24,29 @@ import com.intellij.openapi.util.Conditions
|
|||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import com.intellij.psi.PsiMethod
|
import com.intellij.psi.PsiMethod
|
||||||
import com.intellij.psi.PsiParameter
|
import com.intellij.psi.PsiParameter
|
||||||
import com.intellij.psi.PsiReference
|
|
||||||
import com.intellij.psi.impl.search.ConstructorReferencesSearchHelper
|
|
||||||
import com.intellij.psi.search.SearchRequestCollector
|
|
||||||
import com.intellij.psi.search.SearchSession
|
|
||||||
import com.intellij.psi.search.searches.ReferencesSearch
|
import com.intellij.psi.search.searches.ReferencesSearch
|
||||||
import com.intellij.refactoring.safeDelete.JavaSafeDeleteProcessor
|
import com.intellij.refactoring.safeDelete.JavaSafeDeleteProcessor
|
||||||
import com.intellij.refactoring.safeDelete.NonCodeUsageSearchInfo
|
import com.intellij.refactoring.safeDelete.NonCodeUsageSearchInfo
|
||||||
import com.intellij.refactoring.safeDelete.usageInfo.*
|
import com.intellij.refactoring.safeDelete.usageInfo.SafeDeleteOverrideAnnotation
|
||||||
|
import com.intellij.refactoring.safeDelete.usageInfo.SafeDeleteOverridingMethodUsageInfo
|
||||||
|
import com.intellij.refactoring.safeDelete.usageInfo.SafeDeleteReferenceJavaDeleteUsageInfo
|
||||||
|
import com.intellij.refactoring.safeDelete.usageInfo.SafeDeleteReferenceSimpleDeleteUsageInfo
|
||||||
import com.intellij.usageView.UsageInfo
|
import com.intellij.usageView.UsageInfo
|
||||||
import com.intellij.util.Processor
|
|
||||||
import org.jetbrains.kotlin.asJava.*
|
import org.jetbrains.kotlin.asJava.*
|
||||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.Modality
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
import org.jetbrains.kotlin.psi.*
|
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
|
||||||
import org.jetbrains.kotlin.lexer.JetTokens
|
|
||||||
import org.jetbrains.kotlin.idea.JetBundle
|
import org.jetbrains.kotlin.idea.JetBundle
|
||||||
|
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||||
import org.jetbrains.kotlin.idea.refactoring.JetRefactoringUtil
|
import org.jetbrains.kotlin.idea.refactoring.JetRefactoringUtil
|
||||||
import org.jetbrains.kotlin.idea.references.JetReference
|
import org.jetbrains.kotlin.idea.references.JetReference
|
||||||
import java.util.*
|
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
|
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.deleteElementAndCleanParent
|
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
|
||||||
import org.jetbrains.kotlin.idea.search.usagesSearch.processDelegationCallConstructorUsages
|
import org.jetbrains.kotlin.idea.search.usagesSearch.processDelegationCallConstructorUsages
|
||||||
|
import org.jetbrains.kotlin.lexer.JetTokens
|
||||||
|
import org.jetbrains.kotlin.psi.*
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.deleteElementAndCleanParent
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
|
||||||
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
|
import java.util.ArrayList
|
||||||
|
import java.util.Collections
|
||||||
|
|
||||||
public class KotlinSafeDeleteProcessor : JavaSafeDeleteProcessor() {
|
public class KotlinSafeDeleteProcessor : JavaSafeDeleteProcessor() {
|
||||||
override fun handlesElement(element: PsiElement): Boolean = element.canDeleteElement()
|
override fun handlesElement(element: PsiElement): Boolean = element.canDeleteElement()
|
||||||
@@ -327,4 +326,18 @@ public class KotlinSafeDeleteProcessor : JavaSafeDeleteProcessor() {
|
|||||||
else -> super.getElementsToSearch(element, module, allElementsToDelete)
|
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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
package source
|
||||||
|
|
||||||
|
import library.B
|
||||||
|
import library.bar
|
||||||
|
|
||||||
Reference in New Issue
Block a user