diff --git a/.idea/modules.xml b/.idea/modules.xml index d9d1d0e7c4c6..288a4a55fa7a 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -1238,6 +1238,7 @@ + diff --git a/java/java-impl-refactorings/src/com/intellij/refactoring/safeDelete/JavaSafeDeleteDelegateImpl.java b/java/java-impl-refactorings/src/com/intellij/refactoring/safeDelete/JavaSafeDeleteDelegateImpl.java index 29a3afa4fac3..be9fb2a88318 100644 --- a/java/java-impl-refactorings/src/com/intellij/refactoring/safeDelete/JavaSafeDeleteDelegateImpl.java +++ b/java/java-impl-refactorings/src/com/intellij/refactoring/safeDelete/JavaSafeDeleteDelegateImpl.java @@ -97,4 +97,22 @@ public class JavaSafeDeleteDelegateImpl implements JavaSafeDeleteDelegate { }); } } + + @Override + public void createJavaTypeParameterUsageInfo(@NotNull PsiReference reference, @NotNull List usages, @NotNull PsiElement typeParameter, + int paramsCount, + int index) { + if (reference instanceof PsiJavaCodeReferenceElement) { + final PsiReferenceParameterList parameterList = ((PsiJavaCodeReferenceElement)reference).getParameterList(); + if (parameterList != null) { + PsiTypeElement[] typeArgs = parameterList.getTypeParameterElements(); + if (typeArgs.length > index) { + if (typeArgs.length == 1 && paramsCount > 1 && typeArgs[0].getType() instanceof PsiDiamondType) { + return; + } + usages.add(new SafeDeleteReferenceJavaDeleteUsageInfo(typeArgs[index], typeParameter, true)); + } + } + } + } } diff --git a/java/java-impl-refactorings/src/com/intellij/refactoring/safeDelete/JavaSafeDeleteProcessor.java b/java/java-impl-refactorings/src/com/intellij/refactoring/safeDelete/JavaSafeDeleteProcessor.java index fa0d6f6f03ea..a26b29904843 100644 --- a/java/java-impl-refactorings/src/com/intellij/refactoring/safeDelete/JavaSafeDeleteProcessor.java +++ b/java/java-impl-refactorings/src/com/intellij/refactoring/safeDelete/JavaSafeDeleteProcessor.java @@ -668,7 +668,7 @@ public class JavaSafeDeleteProcessor extends SafeDeleteProcessorDelegateBase { return true; } - private static void findTypeParameterExternalUsages(final PsiTypeParameter typeParameter, final Collection usages) { + private static void findTypeParameterExternalUsages(final PsiTypeParameter typeParameter, final List usages) { PsiTypeParameterListOwner owner = typeParameter.getOwner(); if (owner != null) { final PsiTypeParameterList parameterList = owner.getTypeParameterList(); @@ -677,32 +677,16 @@ public class JavaSafeDeleteProcessor extends SafeDeleteProcessorDelegateBase { final int index = parameterList.getTypeParameterIndex(typeParameter); ReferencesSearch.search(owner).forEach(reference -> { - ContainerUtil.addIfNotNull(usages, createJavaTypeParameterUsageInfo(typeParameter, paramsCount, index, reference)); + JavaSafeDeleteDelegate safeDeleteDelegate = JavaSafeDeleteDelegate.EP.forLanguage(reference.getElement().getLanguage()); + if (safeDeleteDelegate != null) { + safeDeleteDelegate.createJavaTypeParameterUsageInfo(reference, usages, typeParameter, paramsCount, index); + } return true; }); } } } - public static UsageInfo createJavaTypeParameterUsageInfo(@NotNull PsiElement typeParameter, - int paramsCount, - int index, - @NotNull PsiReference reference) { - if (reference instanceof PsiJavaCodeReferenceElement) { - final PsiReferenceParameterList parameterList1 = ((PsiJavaCodeReferenceElement)reference).getParameterList(); - if (parameterList1 != null) { - PsiTypeElement[] typeArgs = parameterList1.getTypeParameterElements(); - if (typeArgs.length > index) { - if (typeArgs.length == 1 && paramsCount > 1 && typeArgs[0].getType() instanceof PsiDiamondType) { - return null; - } - return new SafeDeleteReferenceJavaDeleteUsageInfo(typeArgs[index], typeParameter, true); - } - } - } - return null; - } - @Nullable private static Condition findMethodUsages(final PsiMethod psiMethod, final PsiElement[] allElementsToDelete, List usages) { final Collection references = ReferencesSearch.search(psiMethod).findAll(); diff --git a/java/openapi/src/com/intellij/refactoring/safeDelete/JavaSafeDeleteDelegate.java b/java/openapi/src/com/intellij/refactoring/safeDelete/JavaSafeDeleteDelegate.java index 7ab224ba4a65..db14ce44ffbb 100644 --- a/java/openapi/src/com/intellij/refactoring/safeDelete/JavaSafeDeleteDelegate.java +++ b/java/openapi/src/com/intellij/refactoring/safeDelete/JavaSafeDeleteDelegate.java @@ -2,6 +2,7 @@ package com.intellij.refactoring.safeDelete; import com.intellij.lang.LanguageExtension; +import com.intellij.psi.PsiElement; import com.intellij.psi.PsiNamedElement; import com.intellij.psi.PsiReference; import com.intellij.usageView.UsageInfo; @@ -18,8 +19,8 @@ public interface JavaSafeDeleteDelegate { new LanguageExtension<>("com.intellij.refactoring.safeDelete.JavaSafeDeleteDelegate"); /** - * Method is used to create usage information according to the input reference to the method - * and parameter that belongs to the method. + * Method is used to create usage information according to the input reference to the parameter. + *

* The result will be filled into the list of the usages. *

The method should be called under read action. * A caller should be also aware that an implementation may use an index access, @@ -31,4 +32,16 @@ public interface JavaSafeDeleteDelegate { @NotNull PsiNamedElement parameter, int paramIdx, boolean isVararg); + /** + * Method is used to create usage information for type parameter. + *

+ *

The method should be called under read action. + * A caller should be also aware that an implementation may use an index access, + * so using the method in EDT may lead to get the exception from {@link SlowOperations#assertSlowOperationsAreAllowed()} + */ + void createJavaTypeParameterUsageInfo(@NotNull PsiReference reference, + @NotNull List usages, + @NotNull PsiElement typeParameter, + int paramsCount, + int index); } diff --git a/platform/build-scripts/src/org/jetbrains/intellij/build/kotlin/KotlinPluginBuilder.kt b/platform/build-scripts/src/org/jetbrains/intellij/build/kotlin/KotlinPluginBuilder.kt index cea05d69fefa..074541ad633c 100644 --- a/platform/build-scripts/src/org/jetbrains/intellij/build/kotlin/KotlinPluginBuilder.kt +++ b/platform/build-scripts/src/org/jetbrains/intellij/build/kotlin/KotlinPluginBuilder.kt @@ -176,6 +176,7 @@ object KotlinPluginBuilder { "kotlin.uast.uast-kotlin-idea-fir", "kotlin.fir.fir-low-level-api-ide-impl", "kotlin.navigation", + "kotlin.refactorings.common", "kotlin.refactorings.k2", "kotlin.refactorings.rename.k2", ) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/safeDelete/JavaSafeDeleteDelegateForGroovy.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/safeDelete/JavaSafeDeleteDelegateForGroovy.java index a2a793e1e9c6..e41a02e8e2c0 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/safeDelete/JavaSafeDeleteDelegateForGroovy.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/safeDelete/JavaSafeDeleteDelegateForGroovy.java @@ -5,18 +5,25 @@ import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiNamedElement; import com.intellij.psi.PsiReference; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.util.PsiUtilCore; import com.intellij.refactoring.safeDelete.JavaSafeDeleteDelegate; import com.intellij.refactoring.safeDelete.usageInfo.SafeDeleteReferenceJavaDeleteUsageInfo; import com.intellij.usageView.UsageInfo; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.lang.groovydoc.psi.api.GrDocMethodParameter; import org.jetbrains.plugins.groovy.lang.groovydoc.psi.api.GrDocMethodReference; import org.jetbrains.plugins.groovy.lang.groovydoc.psi.api.GrDocReferenceElement; +import org.jetbrains.plugins.groovy.lang.psi.GroovyElementTypes; import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrSignature; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrCall; +import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeArgumentList; +import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeElement; import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil; +import org.jetbrains.plugins.groovy.lang.psi.impl.types.GrCodeReferenceElementImpl; import java.util.ArrayList; import java.util.Arrays; @@ -74,4 +81,42 @@ public class JavaSafeDeleteDelegateForGroovy implements JavaSafeDeleteDelegate { }); } } + + @Override + public void createJavaTypeParameterUsageInfo(@NotNull PsiReference reference, + @NotNull List usages, + @NotNull PsiElement typeParameter, + int paramsCount, + int index) { + if (reference instanceof GrCodeReferenceElementImpl) { + final @Nullable GrTypeArgumentList parameterList = ((GrCodeReferenceElementImpl)reference).getTypeArgumentList(); + if (parameterList != null) { + GrTypeElement[] typeArgs = parameterList.getTypeArgumentElements(); + if (typeArgs.length > index) { + usages.add(new SafeDeleteReferenceJavaDeleteUsageInfo(typeArgs.length == 1 ? parameterList : typeArgs[index], typeParameter, true) { + @Override + public void deleteElement() throws IncorrectOperationException { + PsiElement element = getElement(); + if (element != null) { + PsiElement parent = element.getParent(); + if (parent != null && parent.isValid()) { + @Nullable PsiElement next = PsiTreeUtil.skipWhitespacesAndCommentsForward(element); + if (next != null && PsiUtilCore.getElementType(next) == GroovyElementTypes.T_COMMA) { + next.delete(); + } + else { + @Nullable PsiElement prev = PsiTreeUtil.skipWhitespacesAndCommentsBackward(element); + if (prev != null && PsiUtilCore.getElementType(prev) == GroovyElementTypes.T_COMMA) { + prev.delete(); + } + } + } + } + super.deleteElement(); + } + }); + } + } + } + } } diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/safeDelete/SafeDeleteJavaParameterTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/safeDelete/SafeDeleteJavaTest.groovy similarity index 76% rename from plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/safeDelete/SafeDeleteJavaParameterTest.groovy rename to plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/safeDelete/SafeDeleteJavaTest.groovy index 864a8bbd4d14..308858f980a0 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/safeDelete/SafeDeleteJavaParameterTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/safeDelete/SafeDeleteJavaTest.groovy @@ -10,7 +10,7 @@ import org.jetbrains.plugins.groovy.util.TestUtils /** * @author Max Medvedev */ -class SafeDeleteJavaParameterTest extends LightGroovyTestCase { +class SafeDeleteJavaTest extends LightGroovyTestCase { final String basePath = TestUtils.testDataPath + "refactoring/safeDeleteJavaParameter/" @@ -41,6 +41,36 @@ class X{} @see A#foo(long) */ class X{} +''') + } + + void testGroovyTypeArgs() { + doTest('''\ +class A<T> { +} +''', '''\ +class X { + A a = new A() +} +''', '''\ +class X { + A a = new A() +} +''') + } + + void testGroovyTypeArgs2() { + doTest('''\ +class A<T, K> { +} +''', '''\ +class X { + A a = new A() +} +''', '''\ +class X { + A a = new A() +} ''') } diff --git a/plugins/kotlin/idea/kotlin.idea.iml b/plugins/kotlin/idea/kotlin.idea.iml index 8d723f02b675..9c51873ed472 100644 --- a/plugins/kotlin/idea/kotlin.idea.iml +++ b/plugins/kotlin/idea/kotlin.idea.iml @@ -103,5 +103,6 @@ + \ No newline at end of file diff --git a/plugins/kotlin/intellij.kotlin.plugin.community.main.iml b/plugins/kotlin/intellij.kotlin.plugin.community.main.iml index da43b9d1b796..d2636a84b36b 100644 --- a/plugins/kotlin/intellij.kotlin.plugin.community.main.iml +++ b/plugins/kotlin/intellij.kotlin.plugin.community.main.iml @@ -184,5 +184,6 @@ + \ No newline at end of file diff --git a/plugins/kotlin/plugin/k1/kotlin.plugin.k1.iml b/plugins/kotlin/plugin/k1/kotlin.plugin.k1.iml index cdef461c8562..ec29b55ea010 100644 --- a/plugins/kotlin/plugin/k1/kotlin.plugin.k1.iml +++ b/plugins/kotlin/plugin/k1/kotlin.plugin.k1.iml @@ -144,5 +144,6 @@ + \ No newline at end of file diff --git a/plugins/kotlin/plugin/k2/kotlin.plugin.k2.iml b/plugins/kotlin/plugin/k2/kotlin.plugin.k2.iml index 5b672e39619a..4fff74a46b5c 100644 --- a/plugins/kotlin/plugin/k2/kotlin.plugin.k2.iml +++ b/plugins/kotlin/plugin/k2/kotlin.plugin.k2.iml @@ -95,5 +95,6 @@ + \ No newline at end of file diff --git a/plugins/kotlin/refactorings/kotlin.refactorings.common/kotlin.refactorings.common.iml b/plugins/kotlin/refactorings/kotlin.refactorings.common/kotlin.refactorings.common.iml new file mode 100644 index 000000000000..37ccf1230cdc --- /dev/null +++ b/plugins/kotlin/refactorings/kotlin.refactorings.common/kotlin.refactorings.common.iml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/plugins/kotlin/refactorings/kotlin.refactorings.common/src/org/jetbrains/kotlin/idea/refactoring/deleteUtil.kt b/plugins/kotlin/refactorings/kotlin.refactorings.common/src/org/jetbrains/kotlin/idea/refactoring/deleteUtil.kt new file mode 100644 index 000000000000..e09501449585 --- /dev/null +++ b/plugins/kotlin/refactorings/kotlin.refactorings.common/src/org/jetbrains/kotlin/idea/refactoring/deleteUtil.kt @@ -0,0 +1,32 @@ +// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package org.jetbrains.kotlin.idea.refactoring + +import com.intellij.psi.PsiElement +import com.intellij.psi.util.PsiTreeUtil +import com.intellij.psi.util.elementType +import org.jetbrains.kotlin.lexer.KtTokens + + +fun deleteBracesAroundEmptyList(element: PsiElement?) { + val nextSibling = PsiTreeUtil.skipWhitespacesAndCommentsForward(element) + val prevSibling = PsiTreeUtil.skipWhitespacesAndCommentsBackward(element) + if (nextSibling != null && nextSibling.elementType == KtTokens.GT && + prevSibling != null && prevSibling.elementType == KtTokens.LT) { + //keep comments + nextSibling.delete() + prevSibling.delete() + } +} + + +fun deleteSeparatingComma(e: PsiElement?) { + val nextSibling = PsiTreeUtil.skipWhitespacesAndCommentsForward(e) + if (nextSibling != null && nextSibling.elementType == KtTokens.COMMA) { + nextSibling.delete() + } else { + val prevSibling = PsiTreeUtil.skipWhitespacesAndCommentsBackward(e) + if (prevSibling != null && prevSibling.elementType == KtTokens.COMMA) { + prevSibling.delete() + } + } +} \ No newline at end of file diff --git a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/refactoring/safeDelete/KotlinJavaSafeDeleteDelegate.kt b/plugins/kotlin/refactorings/kotlin.refactorings.common/src/org/jetbrains/kotlin/idea/refactoring/safeDelete/KotlinJavaSafeDeleteDelegate.kt similarity index 76% rename from plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/refactoring/safeDelete/KotlinJavaSafeDeleteDelegate.kt rename to plugins/kotlin/refactorings/kotlin.refactorings.common/src/org/jetbrains/kotlin/idea/refactoring/safeDelete/KotlinJavaSafeDeleteDelegate.kt index 6deb19ae045a..853a8743c1be 100644 --- a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/refactoring/safeDelete/KotlinJavaSafeDeleteDelegate.kt +++ b/plugins/kotlin/refactorings/kotlin.refactorings.common/src/org/jetbrains/kotlin/idea/refactoring/safeDelete/KotlinJavaSafeDeleteDelegate.kt @@ -1,10 +1,11 @@ // Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. - package org.jetbrains.kotlin.idea.refactoring.safeDelete +import com.intellij.psi.PsiElement import com.intellij.psi.PsiNamedElement import com.intellij.psi.PsiReference import com.intellij.psi.util.PsiTreeUtil +import com.intellij.psi.util.isAncestor import com.intellij.refactoring.safeDelete.JavaSafeDeleteDelegate import com.intellij.refactoring.safeDelete.usageInfo.SafeDeleteReferenceSimpleDeleteUsageInfo import com.intellij.usageView.UsageInfo @@ -12,9 +13,9 @@ import org.jetbrains.kotlin.asJava.unwrapped import org.jetbrains.kotlin.idea.references.KtReference import org.jetbrains.kotlin.psi.KtCallExpression import org.jetbrains.kotlin.psi.KtReferenceExpression +import org.jetbrains.kotlin.psi.KtUserType import org.jetbrains.kotlin.psi.KtValueArgument import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType -import org.jetbrains.kotlin.psi.psiUtil.isAncestor import org.jetbrains.kotlin.psi.psiUtil.parameterIndex class KotlinJavaSafeDeleteDelegate : JavaSafeDeleteDelegate { @@ -33,13 +34,13 @@ class KotlinJavaSafeDeleteDelegate : JavaSafeDeleteDelegate { val parameterIndex = originalParameter.parameterIndex() if (parameterIndex < 0) return - + val target = reference.resolve() ?: return if (!PsiTreeUtil.isAncestor(target, originalParameter, true)) { return } - + val callExpression = element.getNonStrictParentOfType() ?: return val calleeExpression = callExpression.calleeExpression @@ -64,4 +65,24 @@ class KotlinJavaSafeDeleteDelegate : JavaSafeDeleteDelegate { } } } -} + + override fun createJavaTypeParameterUsageInfo( + reference: PsiReference, + usages: MutableList, + typeParameter: PsiElement, + paramsCount: Int, + index: Int + ) { + val referencedElement = reference.element + + val argList = referencedElement.getNonStrictParentOfType()?.typeArgumentList + ?: referencedElement.getNonStrictParentOfType()?.typeArgumentList + + if (argList != null) { + val projections = argList.arguments + if (index < projections.size) { + usages.add(SafeDeleteTypeArgumentUsageInfo(projections[index], referencedElement)) + } + } + } +} \ No newline at end of file diff --git a/plugins/kotlin/refactorings/kotlin.refactorings.common/src/org/jetbrains/kotlin/idea/refactoring/safeDelete/SafeDeleteTypeArgumentUsageInfo.kt b/plugins/kotlin/refactorings/kotlin.refactorings.common/src/org/jetbrains/kotlin/idea/refactoring/safeDelete/SafeDeleteTypeArgumentUsageInfo.kt new file mode 100644 index 000000000000..c36f10a66f16 --- /dev/null +++ b/plugins/kotlin/refactorings/kotlin.refactorings.common/src/org/jetbrains/kotlin/idea/refactoring/safeDelete/SafeDeleteTypeArgumentUsageInfo.kt @@ -0,0 +1,24 @@ +// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. + +package org.jetbrains.kotlin.idea.refactoring.safeDelete + +import com.intellij.psi.PsiElement +import com.intellij.refactoring.safeDelete.usageInfo.SafeDeleteReferenceSimpleDeleteUsageInfo +import org.jetbrains.kotlin.idea.refactoring.deleteBracesAroundEmptyList +import org.jetbrains.kotlin.idea.refactoring.deleteSeparatingComma +import org.jetbrains.kotlin.psi.KtTypeProjection + +class SafeDeleteTypeArgumentUsageInfo( + projection: KtTypeProjection, + referenceElement: PsiElement +) : SafeDeleteReferenceSimpleDeleteUsageInfo(projection, referenceElement, true) { + override fun deleteElement() { + val e = element + if (e != null) { + deleteSeparatingComma(e) + deleteBracesAroundEmptyList(e) + + e.delete() + } + } +} diff --git a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/refactoring/safeDelete/SafeDeleteValueArgumentListUsageInfo.kt b/plugins/kotlin/refactorings/kotlin.refactorings.common/src/org/jetbrains/kotlin/idea/refactoring/safeDelete/SafeDeleteValueArgumentListUsageInfo.kt similarity index 92% rename from plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/refactoring/safeDelete/SafeDeleteValueArgumentListUsageInfo.kt rename to plugins/kotlin/refactorings/kotlin.refactorings.common/src/org/jetbrains/kotlin/idea/refactoring/safeDelete/SafeDeleteValueArgumentListUsageInfo.kt index 5f6409c2d32b..c2133c5594d0 100644 --- a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/refactoring/safeDelete/SafeDeleteValueArgumentListUsageInfo.kt +++ b/plugins/kotlin/refactorings/kotlin.refactorings.common/src/org/jetbrains/kotlin/idea/refactoring/safeDelete/SafeDeleteValueArgumentListUsageInfo.kt @@ -1,4 +1,4 @@ -// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package org.jetbrains.kotlin.idea.refactoring.safeDelete diff --git a/plugins/kotlin/refactorings/kotlin.refactorings.k2/kotlin.refactorings.k2.iml b/plugins/kotlin/refactorings/kotlin.refactorings.k2/kotlin.refactorings.k2.iml index bb22318e8088..3b52f2c1f345 100644 --- a/plugins/kotlin/refactorings/kotlin.refactorings.k2/kotlin.refactorings.k2.iml +++ b/plugins/kotlin/refactorings/kotlin.refactorings.k2/kotlin.refactorings.k2.iml @@ -19,5 +19,6 @@ + \ No newline at end of file diff --git a/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/refactoring/safeDelete/KotlinFirSafeDeleteProcessor.kt b/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/refactoring/safeDelete/KotlinFirSafeDeleteProcessor.kt index dbc0da326135..0500e7ecf858 100644 --- a/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/refactoring/safeDelete/KotlinFirSafeDeleteProcessor.kt +++ b/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/refactoring/safeDelete/KotlinFirSafeDeleteProcessor.kt @@ -6,10 +6,11 @@ import com.intellij.openapi.project.Project import com.intellij.psi.ElementDescriptionUtil import com.intellij.psi.PsiElement import com.intellij.psi.search.searches.ReferencesSearch -import com.intellij.psi.util.PsiTreeUtil -import com.intellij.psi.util.elementType import com.intellij.refactoring.RefactoringBundle -import com.intellij.refactoring.safeDelete.* +import com.intellij.refactoring.safeDelete.JavaSafeDeleteDelegate +import com.intellij.refactoring.safeDelete.NonCodeUsageSearchInfo +import com.intellij.refactoring.safeDelete.SafeDeleteProcessor +import com.intellij.refactoring.safeDelete.SafeDeleteProcessorDelegateBase import com.intellij.refactoring.safeDelete.usageInfo.SafeDeleteReferenceSimpleDeleteUsageInfo import com.intellij.refactoring.util.RefactoringDescriptionLocation import com.intellij.usageView.UsageInfo @@ -19,9 +20,7 @@ import org.jetbrains.kotlin.analysis.api.analyzeInModalWindow import org.jetbrains.kotlin.analysis.api.symbols.KtCallableSymbol import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithModality import org.jetbrains.kotlin.descriptors.Modality -import org.jetbrains.kotlin.idea.refactoring.KotlinFirRefactoringsSettings -import org.jetbrains.kotlin.idea.refactoring.KotlinK2RefactoringsBundle -import org.jetbrains.kotlin.idea.refactoring.canDeleteElement +import org.jetbrains.kotlin.idea.refactoring.* import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType @@ -58,20 +57,13 @@ class KotlinFirSafeDeleteProcessor : SafeDeleteProcessorDelegateBase() { val parameterList = owner.typeParameters val parameterIndex = parameterList.indexOf(element) for (reference in ReferencesSearch.search(owner)) { - val referencedElement = reference.element - - val argList = referencedElement.getNonStrictParentOfType()?.typeArgumentList - ?: referencedElement.getNonStrictParentOfType()?.typeArgumentList - - if (argList != null) { - val projections = argList.arguments - if (parameterIndex < projections.size) { - result.add(SafeDeleteTypeArgumentUsageInfo(projections[parameterIndex], element)) - } - } else { - JavaSafeDeleteProcessor.createJavaTypeParameterUsageInfo(element, parameterList.size, parameterIndex, reference) - ?.let { result.add(it) } - } + JavaSafeDeleteDelegate.EP.forLanguage(reference.element.language).createJavaTypeParameterUsageInfo( + reference, + result, + element, + parameterList.size, + parameterIndex + ) } } } @@ -196,42 +188,3 @@ class KotlinFirSafeDeleteProcessor : SafeDeleteProcessorDelegateBase() { } } } - -class SafeDeleteTypeArgumentUsageInfo( - projection: KtTypeProjection, - referenceElement: PsiElement -) : SafeDeleteReferenceSimpleDeleteUsageInfo(projection, referenceElement, true) { - override fun deleteElement() { - val e = element - if (e != null) { - deleteSeparatingComma(e) - deleteBracesAroundEmptyList(e) - - e.delete() - } - } -} - -private fun deleteBracesAroundEmptyList(element: PsiElement?) { - val nextSibling = PsiTreeUtil.skipWhitespacesAndCommentsForward(element) - val prevSibling = PsiTreeUtil.skipWhitespacesAndCommentsBackward(element) - if (nextSibling != null && nextSibling.elementType == KtTokens.GT && - prevSibling != null && prevSibling.elementType == KtTokens.LT) { - //keep comments - nextSibling.delete() - prevSibling.delete() - } -} - - -private fun deleteSeparatingComma(e: PsiElement?) { - val nextSibling = PsiTreeUtil.skipWhitespacesAndCommentsForward(e) - if (nextSibling != null && nextSibling.elementType == KtTokens.COMMA) { - nextSibling.delete() - } else { - val prevSibling = PsiTreeUtil.skipWhitespacesAndCommentsBackward(e) - if (prevSibling != null && prevSibling.elementType == KtTokens.COMMA) { - prevSibling.delete() - } - } -} \ No newline at end of file