Safe Delete: Delete interface reference from super-type list when applying Safe Delete to Java interface
#KT-11282 Fixed
This commit is contained in:
@@ -35,6 +35,7 @@ Issues fixed:
|
||||
- [KT-11617](https://youtrack.jetbrains.com/issue/KT-11617) Fixed title of Introduce Parameter declaration chooser
|
||||
- [KT-11817](https://youtrack.jetbrains.com/issue/KT-11817) Fixed rename of Kotlin enum constants through Java references
|
||||
- [KT-11816](https://youtrack.jetbrains.com/issue/KT-11816) Fixed usages search for Safe Delete on simple enum entries
|
||||
- [KT-11282](https://youtrack.jetbrains.com/issue/KT-11282) Delete interface reference from super-type list when applying Safe Delete to Java interface
|
||||
|
||||
#### Debugger
|
||||
|
||||
|
||||
@@ -17,7 +17,13 @@
|
||||
package org.jetbrains.kotlin.psi;
|
||||
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.psi.PsiComment;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiWhiteSpace;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.lexer.KtTokens;
|
||||
import org.jetbrains.kotlin.psi.stubs.KotlinPlaceHolderStub;
|
||||
import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementTypes;
|
||||
|
||||
@@ -38,6 +44,20 @@ public class KtSuperTypeList extends KtElementImplStub<KotlinPlaceHolderStub<KtS
|
||||
return visitor.visitSuperTypeList(this, data);
|
||||
}
|
||||
|
||||
public void removeEntry(@NotNull KtSuperTypeListEntry entry) {
|
||||
EditCommaSeparatedListHelper.INSTANCE.removeItem(entry);
|
||||
if (getEntries().isEmpty()) {
|
||||
delete();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete() throws IncorrectOperationException {
|
||||
PsiElement left = PsiTreeUtil.skipSiblingsBackward(this, PsiWhiteSpace.class, PsiComment.class);
|
||||
if (left == null || left.getNode().getElementType() != KtTokens.COLON) left = this;
|
||||
getParent().deleteChildRange(left, this);
|
||||
}
|
||||
|
||||
public List<KtSuperTypeListEntry> getEntries() {
|
||||
return Arrays.asList(getStubOrPsiChildren(KtStubElementTypes.SUPER_TYPE_LIST_ENTRIES, KtSuperTypeListEntry.ARRAY_FACTORY));
|
||||
}
|
||||
|
||||
@@ -531,6 +531,7 @@ fun main(args: Array<String>) {
|
||||
testClass<AbstractSafeDeleteTest>() {
|
||||
model("refactoring/safeDelete/deleteClass/kotlinClass", testMethod = "doClassTest")
|
||||
model("refactoring/safeDelete/deleteClass/kotlinClassWithJava", testMethod = "doClassTestWithJava")
|
||||
model("refactoring/safeDelete/deleteClass/javaClassWithKotlin", extension = "java", testMethod = "doJavaClassTest")
|
||||
model("refactoring/safeDelete/deleteObject/kotlinObject", testMethod = "doObjectTest")
|
||||
model("refactoring/safeDelete/deleteFunction/kotlinFunction", testMethod = "doFunctionTest")
|
||||
model("refactoring/safeDelete/deleteFunction/kotlinFunctionWithJava", testMethod = "doFunctionTestWithJava")
|
||||
|
||||
@@ -45,6 +45,7 @@ import org.jetbrains.kotlin.idea.search.usagesSearch.processDelegationCallConstr
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getParentOfTypeAndBranch
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.utils.SmartSet
|
||||
import org.jetbrains.kotlin.utils.ifEmpty
|
||||
@@ -99,6 +100,8 @@ class KotlinSafeDeleteProcessor : JavaSafeDeleteProcessor() {
|
||||
else -> {
|
||||
usageElement.getNonStrictParentOfType<KtImportDirective>()?.let { importDirective ->
|
||||
SafeDeleteImportDirectiveUsageInfo(importDirective, element.unwrapped as KtDeclaration)
|
||||
} ?: usageElement.getParentOfTypeAndBranch<KtSuperTypeEntry> { typeReference }?.let {
|
||||
if (element is PsiClass && element.isInterface) SafeDeleteSuperTypeUsageInfo(it, element) else usageInfo
|
||||
} ?: if (forceReferencedElementUnwrapping) {
|
||||
SafeDeleteReferenceJavaDeleteUsageInfo(usageElement, element.unwrapped, usageInfo.isSafeDelete)
|
||||
} else usageInfo
|
||||
@@ -214,6 +217,9 @@ class KotlinSafeDeleteProcessor : JavaSafeDeleteProcessor() {
|
||||
is PsiMethod ->
|
||||
findUsagesByJavaProcessor(element, false)
|
||||
|
||||
is PsiClass ->
|
||||
findUsagesByJavaProcessor(element, false)
|
||||
|
||||
is KtProperty -> {
|
||||
if (!LightClassUtil.canGenerateLightClass(element)) {
|
||||
findKotlinDeclarationUsages(element)
|
||||
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
package org.jetbrains.kotlin.idea.refactoring.safeDelete
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.refactoring.safeDelete.usageInfo.SafeDeleteReferenceUsageInfo
|
||||
import org.jetbrains.kotlin.psi.KtSuperTypeEntry
|
||||
import org.jetbrains.kotlin.psi.KtSuperTypeList
|
||||
|
||||
class SafeDeleteSuperTypeUsageInfo(
|
||||
entry: KtSuperTypeEntry,
|
||||
referencedElement: PsiElement
|
||||
) : SafeDeleteReferenceUsageInfo(entry, referencedElement, true) {
|
||||
private val entry: KtSuperTypeEntry?
|
||||
get() = element as? KtSuperTypeEntry
|
||||
|
||||
override fun deleteElement() {
|
||||
val entry = entry ?: return
|
||||
(entry.parent as? KtSuperTypeList)?.removeEntry(entry)
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.refactoring.safeDelete
|
||||
|
||||
import com.intellij.psi.PsiClass
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiMethod
|
||||
import com.intellij.psi.search.searches.OverridingMethodsSearch
|
||||
@@ -36,6 +37,7 @@ fun PsiElement.canDeleteElement(): Boolean {
|
||||
|| this is KtSecondaryConstructor
|
||||
|| this is KtNamedFunction
|
||||
|| this is PsiMethod
|
||||
|| this is PsiClass
|
||||
|| this is KtProperty
|
||||
|| this is KtTypeParameter
|
||||
}
|
||||
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
public interface <caret>I {
|
||||
|
||||
}
|
||||
|
||||
public interface II {
|
||||
|
||||
}
|
||||
|
||||
public class J implements I, II {
|
||||
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
public interface II {
|
||||
|
||||
}
|
||||
|
||||
public class J implements II {
|
||||
|
||||
}
|
||||
idea/testData/refactoring/safeDelete/deleteClass/javaClassWithKotlin/javaInterfaceInSuperTypeList.kt
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
class K : I, II {
|
||||
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
class K : II {
|
||||
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
public interface <caret>I {
|
||||
|
||||
}
|
||||
|
||||
public class J implements I {
|
||||
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
public class J {
|
||||
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
class K : I {
|
||||
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
class K {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package test
|
||||
|
||||
class B{
|
||||
|
||||
}
|
||||
-1
@@ -1 +0,0 @@
|
||||
interface test.A has 1 usage that is not safe to delete.
|
||||
+5
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.idea.refactoring.safeDelete;
|
||||
import com.intellij.codeInsight.TargetElementUtilBase;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
@@ -58,6 +59,10 @@ public abstract class AbstractSafeDeleteTest extends KotlinLightCodeInsightFixtu
|
||||
doTest(path, KtClass.class, true);
|
||||
}
|
||||
|
||||
public void doJavaClassTest(@NotNull String path) throws Exception {
|
||||
doTest(path, PsiClass.class, true);
|
||||
}
|
||||
|
||||
public void doObjectTest(@NotNull String path) throws Exception {
|
||||
doTest(path, KtObjectDeclaration.class, false);
|
||||
}
|
||||
|
||||
+21
@@ -137,6 +137,27 @@ public class SafeDeleteTestGenerated extends AbstractSafeDeleteTest {
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/refactoring/safeDelete/deleteClass/javaClassWithKotlin")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class JavaClassWithKotlin extends AbstractSafeDeleteTest {
|
||||
public void testAllFilesPresentInJavaClassWithKotlin() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/refactoring/safeDelete/deleteClass/javaClassWithKotlin"), Pattern.compile("^(.+)\\.java$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("javaInterfaceInSuperTypeList.java")
|
||||
public void testJavaInterfaceInSuperTypeList() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/safeDelete/deleteClass/javaClassWithKotlin/javaInterfaceInSuperTypeList.java");
|
||||
doJavaClassTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("javaInterfaceInSuperTypeListLast.java")
|
||||
public void testJavaInterfaceInSuperTypeListLast() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/safeDelete/deleteClass/javaClassWithKotlin/javaInterfaceInSuperTypeListLast.java");
|
||||
doJavaClassTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/refactoring/safeDelete/deleteObject/kotlinObject")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
Reference in New Issue
Block a user