Safe Delete: Skip usages inside of overriding to-be-deleted declarations
#KT-7253 Fixed
This commit is contained in:
+18
-9
@@ -46,6 +46,7 @@ import org.jetbrains.kotlin.lexer.KtTokens
|
|||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
|
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
|
import org.jetbrains.kotlin.utils.SmartSet
|
||||||
import org.jetbrains.kotlin.utils.ifEmpty
|
import org.jetbrains.kotlin.utils.ifEmpty
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
@@ -55,11 +56,12 @@ class KotlinSafeDeleteProcessor : JavaSafeDeleteProcessor() {
|
|||||||
override fun findUsages(
|
override fun findUsages(
|
||||||
element: PsiElement, allElementsToDelete: Array<out PsiElement>, usages: MutableList<UsageInfo>
|
element: PsiElement, allElementsToDelete: Array<out PsiElement>, usages: MutableList<UsageInfo>
|
||||||
): NonCodeUsageSearchInfo {
|
): NonCodeUsageSearchInfo {
|
||||||
val deleteList = allElementsToDelete.toList()
|
val deleteSet = SmartSet.create<PsiElement>()
|
||||||
|
deleteSet.addAll(allElementsToDelete)
|
||||||
|
|
||||||
fun getIgnoranceCondition() = Condition<PsiElement> {
|
fun getIgnoranceCondition() = Condition<PsiElement> {
|
||||||
if (it is KtFile) return@Condition false
|
if (it is KtFile) return@Condition false
|
||||||
deleteList.any { element -> JavaSafeDeleteProcessor.isInside(it, element.unwrapped) }
|
deleteSet.any { element -> JavaSafeDeleteProcessor.isInside(it, element.unwrapped) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getSearchInfo(element: PsiElement): NonCodeUsageSearchInfo {
|
fun getSearchInfo(element: PsiElement): NonCodeUsageSearchInfo {
|
||||||
@@ -70,6 +72,10 @@ class KotlinSafeDeleteProcessor : JavaSafeDeleteProcessor() {
|
|||||||
val javaUsages = ArrayList<UsageInfo>()
|
val javaUsages = ArrayList<UsageInfo>()
|
||||||
val searchInfo = super.findUsages(element, allElementsToDelete, javaUsages)
|
val searchInfo = super.findUsages(element, allElementsToDelete, javaUsages)
|
||||||
|
|
||||||
|
javaUsages.filterIsInstance<SafeDeleteOverridingMethodUsageInfo>().mapNotNullTo(deleteSet) { it.element }
|
||||||
|
|
||||||
|
val ignoranceCondition = getIgnoranceCondition()
|
||||||
|
|
||||||
javaUsages.mapNotNullTo(usages) { usageInfo ->
|
javaUsages.mapNotNullTo(usages) { usageInfo ->
|
||||||
when (usageInfo) {
|
when (usageInfo) {
|
||||||
is SafeDeleteOverridingMethodUsageInfo ->
|
is SafeDeleteOverridingMethodUsageInfo ->
|
||||||
@@ -87,13 +93,16 @@ class KotlinSafeDeleteProcessor : JavaSafeDeleteProcessor() {
|
|||||||
|
|
||||||
is SafeDeleteReferenceJavaDeleteUsageInfo ->
|
is SafeDeleteReferenceJavaDeleteUsageInfo ->
|
||||||
usageInfo.element?.let { usageElement ->
|
usageInfo.element?.let { usageElement ->
|
||||||
if (usageElement.getNonStrictParentOfType<KtValueArgumentName>() != null) null
|
when {
|
||||||
else {
|
usageElement.getNonStrictParentOfType<KtValueArgumentName>() != null -> null
|
||||||
usageElement.getNonStrictParentOfType<KtImportDirective>()?.let { importDirective ->
|
ignoranceCondition.value(usageElement) -> null
|
||||||
SafeDeleteImportDirectiveUsageInfo(importDirective, element.unwrapped as KtDeclaration)
|
else -> {
|
||||||
} ?: if (forceReferencedElementUnwrapping) {
|
usageElement.getNonStrictParentOfType<KtImportDirective>()?.let { importDirective ->
|
||||||
SafeDeleteReferenceJavaDeleteUsageInfo(usageElement, element.unwrapped, usageInfo.isSafeDelete)
|
SafeDeleteImportDirectiveUsageInfo(importDirective, element.unwrapped as KtDeclaration)
|
||||||
} else usageInfo
|
} ?: if (forceReferencedElementUnwrapping) {
|
||||||
|
SafeDeleteReferenceJavaDeleteUsageInfo(usageElement, element.unwrapped, usageInfo.isSafeDelete)
|
||||||
|
} else usageInfo
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
class J implements T {
|
||||||
|
T u;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void foo() {
|
||||||
|
u.foo();
|
||||||
|
}
|
||||||
|
}
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
class J implements T {
|
||||||
|
T u;
|
||||||
|
|
||||||
|
}
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
interface T {
|
||||||
|
fun <caret>foo()
|
||||||
|
}
|
||||||
|
|
||||||
|
class A(val t: T) : T {
|
||||||
|
override fun foo() {
|
||||||
|
t.foo()
|
||||||
|
}
|
||||||
|
}
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
interface T {
|
||||||
|
}
|
||||||
|
|
||||||
|
class A(val t: T) : T {
|
||||||
|
}
|
||||||
+22
@@ -0,0 +1,22 @@
|
|||||||
|
abstract class I implements T {
|
||||||
|
T u;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getFoo() {
|
||||||
|
return u.getFoo();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class J implements T {
|
||||||
|
T u;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getFoo() {
|
||||||
|
return u.getFoo();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setFoo(int value) {
|
||||||
|
u.setFoo(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
abstract class I implements T {
|
||||||
|
T u;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class J implements T {
|
||||||
|
T u;
|
||||||
|
|
||||||
|
}
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
interface T {
|
||||||
|
var <caret>foo: Int
|
||||||
|
}
|
||||||
|
|
||||||
|
class A(val t: T) : T {
|
||||||
|
override var foo: Int
|
||||||
|
get() = t.foo
|
||||||
|
set(value) {
|
||||||
|
t.foo = value
|
||||||
|
}
|
||||||
|
}
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
interface T {
|
||||||
|
}
|
||||||
|
|
||||||
|
class A(val t: T) : T {
|
||||||
|
}
|
||||||
+12
@@ -384,6 +384,12 @@ public class SafeDeleteTestGenerated extends AbstractSafeDeleteTest {
|
|||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/safeDelete/deleteFunction/kotlinFunctionWithJava/secondaryConstructor.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/safeDelete/deleteFunction/kotlinFunctionWithJava/secondaryConstructor.kt");
|
||||||
doFunctionTestWithJava(fileName);
|
doFunctionTestWithJava(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("usageInOverrideToDelete.kt")
|
||||||
|
public void testUsageInOverrideToDelete() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/safeDelete/deleteFunction/kotlinFunctionWithJava/usageInOverrideToDelete.kt");
|
||||||
|
doFunctionTestWithJava(fileName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("idea/testData/refactoring/safeDelete/deleteFunction/javaFunctionWithKotlin")
|
@TestMetadata("idea/testData/refactoring/safeDelete/deleteFunction/javaFunctionWithKotlin")
|
||||||
@@ -627,6 +633,12 @@ public class SafeDeleteTestGenerated extends AbstractSafeDeleteTest {
|
|||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/safeDelete/deleteProperty/kotlinPropertyWithJava/propertyExt.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/safeDelete/deleteProperty/kotlinPropertyWithJava/propertyExt.kt");
|
||||||
doPropertyTestWithJava(fileName);
|
doPropertyTestWithJava(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("usageInOverrideToDelete.kt")
|
||||||
|
public void testUsageInOverrideToDelete() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/safeDelete/deleteProperty/kotlinPropertyWithJava/usageInOverrideToDelete.kt");
|
||||||
|
doPropertyTestWithJava(fileName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("idea/testData/refactoring/safeDelete/deleteProperty/javaPropertyWithKotlin")
|
@TestMetadata("idea/testData/refactoring/safeDelete/deleteProperty/javaPropertyWithKotlin")
|
||||||
|
|||||||
Reference in New Issue
Block a user