remove temporarily copied Java safe delete implementation (the underlying IDEA problem has been fixed)
This commit is contained in:
+9
-156
@@ -17,19 +17,21 @@
|
|||||||
package org.jetbrains.kotlin.idea.refactoring.safeDelete
|
package org.jetbrains.kotlin.idea.refactoring.safeDelete
|
||||||
|
|
||||||
import com.intellij.openapi.application.ApplicationManager
|
import com.intellij.openapi.application.ApplicationManager
|
||||||
import com.intellij.openapi.diagnostic.Logger
|
|
||||||
import com.intellij.openapi.module.Module
|
import com.intellij.openapi.module.Module
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.openapi.util.Condition
|
import com.intellij.openapi.util.Condition
|
||||||
import com.intellij.openapi.util.Conditions
|
import com.intellij.openapi.util.Conditions
|
||||||
import com.intellij.psi.*
|
import com.intellij.psi.PsiElement
|
||||||
|
import com.intellij.psi.PsiMethod
|
||||||
|
import com.intellij.psi.PsiParameter
|
||||||
import com.intellij.psi.search.searches.ReferencesSearch
|
import com.intellij.psi.search.searches.ReferencesSearch
|
||||||
import com.intellij.refactoring.safeDelete.ImportSearcher
|
|
||||||
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
|
||||||
@@ -166,21 +168,11 @@ public class KotlinSafeDeleteProcessor : JavaSafeDeleteProcessor() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun findUsagesByCopiedJavaProcessor(element: PsiElement): NonCodeUsageSearchInfo {
|
|
||||||
if (element is PsiClass) {
|
|
||||||
ClassSearchCopiedFromJava.findClassUsages(element, allElementsToDelete, usages)
|
|
||||||
if (element is PsiTypeParameter) {
|
|
||||||
ClassSearchCopiedFromJava.findTypeParameterExternalUsages(element, usages)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NonCodeUsageSearchInfo(JavaSafeDeleteProcessor.getUsageInsideDeletedFilter(allElementsToDelete), element)
|
|
||||||
}
|
|
||||||
|
|
||||||
return when (element) {
|
return when (element) {
|
||||||
is JetClassOrObject -> {
|
is JetClassOrObject -> {
|
||||||
element.toLightClass()?.let { klass ->
|
element.toLightClass()?.let { klass ->
|
||||||
findDelegationCallUsages(klass)
|
findDelegationCallUsages(klass)
|
||||||
findUsagesByCopiedJavaProcessor(klass)
|
findUsagesByJavaProcessor(klass, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -214,8 +206,7 @@ public class KotlinSafeDeleteProcessor : JavaSafeDeleteProcessor() {
|
|||||||
|
|
||||||
is JetTypeParameter -> {
|
is JetTypeParameter -> {
|
||||||
findTypeParameterUsages(element)
|
findTypeParameterUsages(element)
|
||||||
element.toLightElements().forEach { findUsagesByCopiedJavaProcessor(it) }
|
findUsagesByJavaProcessor(element)
|
||||||
getSearchInfo(element)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
is JetParameter ->
|
is JetParameter ->
|
||||||
@@ -334,142 +325,4 @@ public class KotlinSafeDeleteProcessor : JavaSafeDeleteProcessor() {
|
|||||||
else -> super.getElementsToSearch(element, module, allElementsToDelete)
|
else -> super.getElementsToSearch(element, module, allElementsToDelete)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mostly copied from JavaSafeDeleteProcessor.findClassUsages. Temporary solution
|
|
||||||
private object ClassSearchCopiedFromJava {
|
|
||||||
private val LOG = Logger.getInstance("#" + javaClass<KotlinSafeDeleteProcessor>().canonicalName)
|
|
||||||
|
|
||||||
fun findClassUsages(psiClass: PsiClass, allElementsToDelete: Array<out PsiElement>, usages: MutableList<UsageInfo>) {
|
|
||||||
val justPrivates = containsOnlyPrivates(psiClass)
|
|
||||||
|
|
||||||
ReferencesSearch.search(psiClass).forEach(object : Processor<PsiReference> {
|
|
||||||
override fun process(reference: PsiReference): Boolean {
|
|
||||||
val element = reference.element
|
|
||||||
|
|
||||||
fun isInside(place: PsiElement, ancestors: Array<out PsiElement>): Boolean {
|
|
||||||
for (ancestor in ancestors) {
|
|
||||||
if (JavaSafeDeleteProcessor.isInside(place, ancestor)) return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
fun isInNonStaticImport(element: PsiElement): Boolean {
|
|
||||||
return ImportSearcher.getImport(element, true) != null
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isInside(element, allElementsToDelete)) {
|
|
||||||
val parent = element.parent
|
|
||||||
if (parent is PsiReferenceList) {
|
|
||||||
val pparent = parent.parent
|
|
||||||
if (pparent is PsiClass) {
|
|
||||||
/* If psiClass contains only private members, then it is safe to remove it
|
|
||||||
and change inheritor's extends/implements accordingly */
|
|
||||||
if (justPrivates && element is PsiJavaCodeReferenceElement) {
|
|
||||||
if (parent == pparent.extendsList || parent == pparent.implementsList) {
|
|
||||||
usages.add(SafeDeleteExtendsClassUsageInfo(element, psiClass, pparent))
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
LOG.assertTrue(element.textRange != null)
|
|
||||||
|
|
||||||
val importDirective = getImportDirective(element, element)
|
|
||||||
if (importDirective != null) {
|
|
||||||
usages.add(SafeDeleteReferenceJavaDeleteUsageInfo(importDirective, psiClass, true))
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
val containingFile = psiClass.containingFile
|
|
||||||
val sameFileWithSingleClass = containingFile is PsiClassOwner
|
|
||||||
&& containingFile.classes.size() == 1
|
|
||||||
&& element.containingFile === containingFile
|
|
||||||
|
|
||||||
usages.add(SafeDeleteReferenceJavaDeleteUsageInfo(element, psiClass,
|
|
||||||
sameFileWithSingleClass || isInNonStaticImport(element)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fun findTypeParameterExternalUsages(typeParameter: PsiTypeParameter, usages: MutableCollection<UsageInfo>) {
|
|
||||||
val owner = typeParameter.owner
|
|
||||||
if (owner != null) {
|
|
||||||
val parameterList = owner.typeParameterList
|
|
||||||
if (parameterList != null) {
|
|
||||||
val paramsCount = parameterList.typeParameters.size()
|
|
||||||
val index = parameterList.getTypeParameterIndex(typeParameter)
|
|
||||||
|
|
||||||
ReferencesSearch.search(owner).forEach(object : Processor<PsiReference> {
|
|
||||||
override fun process(reference: PsiReference): Boolean {
|
|
||||||
if (reference is PsiJavaCodeReferenceElement) {
|
|
||||||
val parameterList = reference.parameterList
|
|
||||||
if (parameterList != null) {
|
|
||||||
val typeArgs = parameterList.typeParameterElements
|
|
||||||
if (typeArgs.size() > index) {
|
|
||||||
if (typeArgs.size() == 1 && paramsCount > 1 && typeArgs[0].type is PsiDiamondType) return true
|
|
||||||
usages.add(SafeDeleteReferenceJavaDeleteUsageInfo(typeArgs[index], typeParameter, true))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getImportDirective(element: PsiElement?, original: PsiElement): JetImportDirective? = when (element) {
|
|
||||||
is JetDotQualifiedExpression -> getImportDirective(element.parent, original)
|
|
||||||
is JetNameReferenceExpression -> getImportDirective(element.parent, original)
|
|
||||||
is JetImportDirective -> {
|
|
||||||
val lastChild = element.importedReference
|
|
||||||
if (lastChild == original || (lastChild is JetDotQualifiedExpression && lastChild.selectorExpression == original)) {
|
|
||||||
element
|
|
||||||
} else {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else -> null
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun containsOnlyPrivates(aClass: PsiClass): Boolean {
|
|
||||||
val fields = aClass.fields
|
|
||||||
for (field in fields) {
|
|
||||||
if (!field.hasModifierProperty(PsiModifier.PRIVATE)) return false
|
|
||||||
}
|
|
||||||
|
|
||||||
val methods = aClass.methods
|
|
||||||
for (method in methods) {
|
|
||||||
if (!method.hasModifierProperty(PsiModifier.PRIVATE)) {
|
|
||||||
if (method.isConstructor) {
|
|
||||||
//skip non-private constructors with call to super only
|
|
||||||
val body = method.body
|
|
||||||
if (body != null) {
|
|
||||||
val statements = body.statements
|
|
||||||
if (statements.size() == 0) continue
|
|
||||||
if (statements.size() == 1 && statements[0] is PsiExpressionStatement) {
|
|
||||||
val expression = (statements[0] as PsiExpressionStatement).expression
|
|
||||||
if (expression is PsiMethodCallExpression) {
|
|
||||||
val methodExpression = expression.methodExpression
|
|
||||||
if (methodExpression.text == PsiKeyword.SUPER) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val inners = aClass.innerClasses
|
|
||||||
for (inner in inners) {
|
|
||||||
if (!inner.hasModifierProperty(PsiModifier.PRIVATE)) return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user