diff --git a/ChangeLog.md b/ChangeLog.md index f0afc380014..c72435a3a0c 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -342,6 +342,7 @@ These artifacts include extensions for the types available in the latter JDKs, s - [`KT-14854`](https://youtrack.jetbrains.com/issue/KT-14854) Extract Interface: Fix NPE on dialog opening - [`KT-14814`](https://youtrack.jetbrains.com/issue/KT-14814) Rename: Fix renaming of .kts file to .kt and vice versa - [`KT-14361`](https://youtrack.jetbrains.com/issue/KT-14361) Rename: Do not report redeclaration conflict for private top-level declarations located in different files +- [`KT-14596`](https://youtrack.jetbrains.com/issue/KT-14596) Safe Delete: Fix exception on deleting Java class used in Kotlin import directive(s) ## 1.0.5 diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/safeDelete/KotlinSafeDeleteProcessor.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/safeDelete/KotlinSafeDeleteProcessor.kt index 5b08f173041..d9e0b93e800 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/safeDelete/KotlinSafeDeleteProcessor.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/safeDelete/KotlinSafeDeleteProcessor.kt @@ -102,7 +102,7 @@ class KotlinSafeDeleteProcessor : JavaSafeDeleteProcessor() { ignoranceCondition.value(usageElement) -> null else -> { usageElement.getNonStrictParentOfType()?.let { importDirective -> - SafeDeleteImportDirectiveUsageInfo(importDirective, element.unwrapped as KtDeclaration) + SafeDeleteImportDirectiveUsageInfo(importDirective, element) } ?: usageElement.getParentOfTypeAndBranch { typeReference }?.let { if (element is PsiClass && element.isInterface) SafeDeleteSuperTypeUsageInfo(it, element) else usageInfo } ?: if (forceReferencedElementUnwrapping) { @@ -140,7 +140,7 @@ class KotlinSafeDeleteProcessor : JavaSafeDeleteProcessor() { .filterNot { reference -> getIgnoranceCondition().value(reference.element) } .mapTo(usages) { reference -> reference.element.getNonStrictParentOfType()?.let { importDirective -> - SafeDeleteImportDirectiveUsageInfo(importDirective, element.unwrapped as KtDeclaration) + SafeDeleteImportDirectiveUsageInfo(importDirective, element) } ?: SafeDeleteReferenceSimpleDeleteUsageInfo(element, declaration, false) } diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/safeDelete/SafeDeleteImportDirectiveUsageInfo.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/safeDelete/SafeDeleteImportDirectiveUsageInfo.kt index c56191a103d..401b3cf91ea 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/safeDelete/SafeDeleteImportDirectiveUsageInfo.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/safeDelete/SafeDeleteImportDirectiveUsageInfo.kt @@ -16,17 +16,27 @@ package org.jetbrains.kotlin.idea.refactoring.safeDelete +import com.intellij.psi.PsiElement +import com.intellij.psi.PsiMember import com.intellij.refactoring.safeDelete.usageInfo.SafeDeleteReferenceSimpleDeleteUsageInfo +import org.jetbrains.kotlin.asJava.unwrapped +import org.jetbrains.kotlin.idea.caches.resolve.getJavaMemberDescriptor import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor import org.jetbrains.kotlin.idea.core.targetDescriptors import org.jetbrains.kotlin.psi.KtDeclaration import org.jetbrains.kotlin.psi.KtImportDirective class SafeDeleteImportDirectiveUsageInfo( - importDirective: KtImportDirective, declaration: KtDeclaration + importDirective: KtImportDirective, declaration: PsiElement ) : SafeDeleteReferenceSimpleDeleteUsageInfo(importDirective, declaration, importDirective.isSafeToDelete(declaration)) -private fun KtImportDirective.isSafeToDelete(declaration: KtDeclaration): Boolean { +private fun KtImportDirective.isSafeToDelete(element: PsiElement): Boolean { val referencedDescriptor = targetDescriptors().singleOrNull() ?: return false - return referencedDescriptor == declaration.resolveToDescriptor() + val unwrappedElement = element.unwrapped + val declarationDescriptor = when (unwrappedElement) { + is KtDeclaration -> unwrappedElement.resolveToDescriptor() + is PsiMember -> unwrappedElement.getJavaMemberDescriptor() + else -> return false + } + return referencedDescriptor == declarationDescriptor } diff --git a/idea/testData/refactoring/safeDelete/deleteClass/javaClassWithKotlin/ImportJavaClassToKotlin.java b/idea/testData/refactoring/safeDelete/deleteClass/javaClassWithKotlin/ImportJavaClassToKotlin.java new file mode 100644 index 00000000000..7ce5a544889 --- /dev/null +++ b/idea/testData/refactoring/safeDelete/deleteClass/javaClassWithKotlin/ImportJavaClassToKotlin.java @@ -0,0 +1,7 @@ +public class J { + +} + +class JJ { + +} \ No newline at end of file diff --git a/idea/testData/refactoring/safeDelete/deleteClass/javaClassWithKotlin/ImportJavaClassToKotlin.java.after b/idea/testData/refactoring/safeDelete/deleteClass/javaClassWithKotlin/ImportJavaClassToKotlin.java.after new file mode 100644 index 00000000000..e4254c5979d --- /dev/null +++ b/idea/testData/refactoring/safeDelete/deleteClass/javaClassWithKotlin/ImportJavaClassToKotlin.java.after @@ -0,0 +1,3 @@ +class JJ { + +} \ No newline at end of file diff --git a/idea/testData/refactoring/safeDelete/deleteClass/javaClassWithKotlin/ImportJavaClassToKotlin.kt b/idea/testData/refactoring/safeDelete/deleteClass/javaClassWithKotlin/ImportJavaClassToKotlin.kt new file mode 100644 index 00000000000..51da195c3a6 --- /dev/null +++ b/idea/testData/refactoring/safeDelete/deleteClass/javaClassWithKotlin/ImportJavaClassToKotlin.kt @@ -0,0 +1,5 @@ +import J + +class K { + +} \ No newline at end of file diff --git a/idea/testData/refactoring/safeDelete/deleteClass/javaClassWithKotlin/ImportJavaClassToKotlin.kt.after b/idea/testData/refactoring/safeDelete/deleteClass/javaClassWithKotlin/ImportJavaClassToKotlin.kt.after new file mode 100644 index 00000000000..907ff90fef4 --- /dev/null +++ b/idea/testData/refactoring/safeDelete/deleteClass/javaClassWithKotlin/ImportJavaClassToKotlin.kt.after @@ -0,0 +1,3 @@ +class K { + +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/refactoring/safeDelete/SafeDeleteTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/refactoring/safeDelete/SafeDeleteTestGenerated.java index 93dbcebb5c4..53677a03fc1 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/refactoring/safeDelete/SafeDeleteTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/refactoring/safeDelete/SafeDeleteTestGenerated.java @@ -146,6 +146,12 @@ public class SafeDeleteTestGenerated extends AbstractSafeDeleteTest { KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/refactoring/safeDelete/deleteClass/javaClassWithKotlin"), Pattern.compile("^(.+)\\.java$"), TargetBackend.ANY, true); } + @TestMetadata("ImportJavaClassToKotlin.java") + public void testImportJavaClassToKotlin() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/safeDelete/deleteClass/javaClassWithKotlin/ImportJavaClassToKotlin.java"); + doJavaClassTest(fileName); + } + @TestMetadata("javaInterfaceInSuperTypeList.java") public void testJavaInterfaceInSuperTypeList() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/safeDelete/deleteClass/javaClassWithKotlin/javaInterfaceInSuperTypeList.java");