"Remove parameter" quick fix: Remove unused type parameter used as type projection #KT-23511
This commit is contained in:
committed by
asedunov
parent
3e38bbcb07
commit
20535feb31
@@ -25,10 +25,7 @@ import org.jetbrains.kotlin.idea.caches.resolve.resolveToParameterDescriptorIfAn
|
|||||||
import org.jetbrains.kotlin.idea.intentions.RemoveEmptyPrimaryConstructorIntention
|
import org.jetbrains.kotlin.idea.intentions.RemoveEmptyPrimaryConstructorIntention
|
||||||
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
import org.jetbrains.kotlin.psi.psiUtil.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getChildOfType
|
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getParentOfTypesAndPredicate
|
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
|
||||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||||
|
|
||||||
class RemoveUnusedFunctionParameterFix(parameter: KtParameter) : KotlinQuickFixAction<KtParameter>(parameter) {
|
class RemoveUnusedFunctionParameterFix(parameter: KtParameter) : KotlinQuickFixAction<KtParameter>(parameter) {
|
||||||
@@ -43,13 +40,11 @@ class RemoveUnusedFunctionParameterFix(parameter: KtParameter) : KotlinQuickFixA
|
|||||||
val parameterList = parameter.parent as? KtParameterList ?: return
|
val parameterList = parameter.parent as? KtParameterList ?: return
|
||||||
val parameterDescriptor = parameter.resolveToParameterDescriptorIfAny(BodyResolveMode.FULL) ?: return
|
val parameterDescriptor = parameter.resolveToParameterDescriptorIfAny(BodyResolveMode.FULL) ?: return
|
||||||
val parameterSize = parameterList.parameters.size
|
val parameterSize = parameterList.parameters.size
|
||||||
val redundantTypeParameter = redundantTypeParameter(parameter)
|
val typeParameters = typeParameters(parameter)
|
||||||
val primaryConstructor = parameterList.parent as? KtPrimaryConstructor
|
val primaryConstructor = parameterList.parent as? KtPrimaryConstructor
|
||||||
|
|
||||||
ChangeFunctionSignatureFix.runRemoveParameter(parameterDescriptor, parameter)
|
ChangeFunctionSignatureFix.runRemoveParameter(parameterDescriptor, parameter)
|
||||||
if (redundantTypeParameter != null) {
|
runRemoveUnusedTypeParameters(typeParameters)
|
||||||
runRemoveTypeParameter(redundantTypeParameter)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (parameterSize > 1) {
|
if (parameterSize > 1) {
|
||||||
val nextParameter = parameterList.parameters.getOrNull(parameterDescriptor.index)
|
val nextParameter = parameterList.parameters.getOrNull(parameterDescriptor.index)
|
||||||
@@ -69,26 +64,28 @@ class RemoveUnusedFunctionParameterFix(parameter: KtParameter) : KotlinQuickFixA
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun redundantTypeParameter(parameter: KtParameter): KtTypeParameter? {
|
private fun typeParameters(parameter: KtParameter): List<KtTypeParameter> {
|
||||||
val typeParameter = parameter.typeReference?.typeElement?.getChildOfType<KtNameReferenceExpression>()?.reference?.resolve()
|
val parameterParent = parameter.getParentOfTypesAndPredicate(false, KtNamedFunction::class.java, KtClass::class.java) { true }
|
||||||
as? KtTypeParameter ?: return null
|
return parameter.typeReference?.typeElement
|
||||||
val parameterParent =
|
?.collectDescendantsOfType<KtNameReferenceExpression> { true }
|
||||||
parameter.getParentOfTypesAndPredicate(false, KtNamedFunction::class.java, KtClass::class.java) { true }
|
?.mapNotNull {
|
||||||
val typeParameterParent =
|
val typeParameter = it.reference?.resolve() as? KtTypeParameter ?: return@mapNotNull null
|
||||||
typeParameter.getParentOfTypesAndPredicate(false, KtNamedFunction::class.java, KtClass::class.java) { true }
|
val parent = typeParameter.getParentOfTypesAndPredicate(false, KtNamedFunction::class.java, KtClass::class.java) { true }
|
||||||
return if (parameterParent == typeParameterParent) typeParameter else null
|
if (parent == parameterParent) typeParameter else null
|
||||||
|
} ?: emptyList()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun runRemoveTypeParameter(typeParameter: KtTypeParameter) {
|
private fun runRemoveUnusedTypeParameters(typeParameters: List<KtTypeParameter>) {
|
||||||
if (ReferencesSearch.search(typeParameter).findFirst() != null) return
|
val unusedTypeParams = typeParameters.filter { ReferencesSearch.search(it).findFirst() == null }
|
||||||
|
if (unusedTypeParams.isEmpty()) return
|
||||||
val typeParameterList = typeParameter.parent as? KtTypeParameterList ?: return
|
|
||||||
val typeParameters = typeParameterList.parameters
|
|
||||||
runWriteAction {
|
runWriteAction {
|
||||||
if (typeParameters.size == 1)
|
unusedTypeParams.forEach { typeParameter ->
|
||||||
typeParameterList.delete()
|
val typeParameterList = typeParameter.parent as? KtTypeParameterList ?: return@forEach
|
||||||
else
|
if (typeParameterList.parameters.size == 1)
|
||||||
EditCommaSeparatedListHelper.removeItem(typeParameter)
|
typeParameterList.delete()
|
||||||
|
else
|
||||||
|
EditCommaSeparatedListHelper.removeItem(typeParameter)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,8 +93,7 @@ class RemoveUnusedFunctionParameterFix(parameter: KtParameter) : KotlinQuickFixA
|
|||||||
override fun createAction(diagnostic: Diagnostic): KotlinQuickFixAction<KtParameter>? {
|
override fun createAction(diagnostic: Diagnostic): KotlinQuickFixAction<KtParameter>? {
|
||||||
val parameter = Errors.UNUSED_PARAMETER.cast(diagnostic).psiElement
|
val parameter = Errors.UNUSED_PARAMETER.cast(diagnostic).psiElement
|
||||||
val parameterOwner = parameter.parent.parent
|
val parameterOwner = parameter.parent.parent
|
||||||
if (parameterOwner is KtFunctionLiteral ||
|
if (parameterOwner is KtFunctionLiteral || (parameterOwner is KtNamedFunction && parameterOwner.name == null)) return null
|
||||||
(parameterOwner is KtNamedFunction && parameterOwner.name == null)) return null
|
|
||||||
return RemoveUnusedFunctionParameterFix(parameter)
|
return RemoveUnusedFunctionParameterFix(parameter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
// "Remove parameter 'x'" "true"
|
||||||
|
interface TypeHolder<T, U>
|
||||||
|
|
||||||
|
fun <T, U> baz(<caret>x: TypeHolder<T, U>) {}
|
||||||
|
|
||||||
|
fun test(holder: TypeHolder<String, Int>) {
|
||||||
|
baz(holder)
|
||||||
|
}
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
// "Remove parameter 'x'" "true"
|
||||||
|
interface TypeHolder<T, U>
|
||||||
|
|
||||||
|
fun baz(<caret>) {}
|
||||||
|
|
||||||
|
fun test(holder: TypeHolder<String, Int>) {
|
||||||
|
baz()
|
||||||
|
}
|
||||||
@@ -1739,6 +1739,11 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
|
|||||||
runTest("idea/testData/quickfix/changeSignature/removeUnusedParameterWithTypeParameter6.kt");
|
runTest("idea/testData/quickfix/changeSignature/removeUnusedParameterWithTypeParameter6.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("removeUnusedParameterWithTypeParameter7.kt")
|
||||||
|
public void testRemoveUnusedParameterWithTypeParameter7() throws Exception {
|
||||||
|
runTest("idea/testData/quickfix/changeSignature/removeUnusedParameterWithTypeParameter7.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("removeUnusedPrimaryConstructorParameter.kt")
|
@TestMetadata("removeUnusedPrimaryConstructorParameter.kt")
|
||||||
public void testRemoveUnusedPrimaryConstructorParameter() throws Exception {
|
public void testRemoveUnusedPrimaryConstructorParameter() throws Exception {
|
||||||
runTest("idea/testData/quickfix/changeSignature/removeUnusedPrimaryConstructorParameter.kt");
|
runTest("idea/testData/quickfix/changeSignature/removeUnusedPrimaryConstructorParameter.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user