From 587b0de2b85782fccbc5340e0d672750c9eea174 Mon Sep 17 00:00:00 2001 From: Dmitry Gridin Date: Fri, 25 Oct 2019 15:35:31 +0700 Subject: [PATCH] RemoveExplicitTypeIntention: fix false positive for type aliases #KT-33902 Fixed --- .../intentions/RemoveExplicitTypeIntention.kt | 32 ++++++++++++------- .../quickfix/RemovePsiElementSimpleFix.kt | 2 +- .../lambdaInitializerWithAlias.kt | 9 ++++++ .../lambdaInitializerWithAlias2.kt | 5 +++ .../lambdaInitializerWithAlias2.kt.after | 5 +++ .../intentions/IntentionTestGenerated.java | 10 ++++++ 6 files changed, 51 insertions(+), 12 deletions(-) create mode 100644 idea/testData/intentions/removeExplicitType/lambdaInitializerWithAlias.kt create mode 100644 idea/testData/intentions/removeExplicitType/lambdaInitializerWithAlias2.kt create mode 100644 idea/testData/intentions/removeExplicitType/lambdaInitializerWithAlias2.kt.after diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveExplicitTypeIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveExplicitTypeIntention.kt index 923231f2e6e..f5615571883 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveExplicitTypeIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveExplicitTypeIntention.kt @@ -22,6 +22,7 @@ import com.intellij.openapi.util.TextRange import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.idea.refactoring.addTypeArgumentsIfNeeded import org.jetbrains.kotlin.idea.refactoring.getQualifiedTypeArgumentList +import org.jetbrains.kotlin.idea.references.mainReference import org.jetbrains.kotlin.idea.search.usagesSearch.descriptor import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.endOffset @@ -68,7 +69,7 @@ class RemoveExplicitTypeIntention : SelfTargetingRangeIntention TextRange(element.startOffset, initializer.startOffset - 1) @@ -78,18 +79,27 @@ class RemoveExplicitTypeIntention : SelfTargetingRangeIntention initializer.valueParameters - is KtNamedFunction -> initializer.valueParameters - else -> emptyList() + val typeElement = typeReference.typeElement ?: return true + return when (typeElement) { + is KtFunctionType -> { + if (typeElement.receiver != null) return false + if (typeElement.parameters.isEmpty()) return true + val valueParameters = when (initializer) { + is KtLambdaExpression -> initializer.valueParameters + is KtNamedFunction -> initializer.valueParameters + else -> emptyList() + } + valueParameters.isNotEmpty() && valueParameters.none { it.typeReference == null } + } + is KtUserType -> { + val typeAlias = typeElement.referenceExpression?.mainReference?.resolve() as? KtTypeAlias ?: return true + return redundantTypeSpecification(typeAlias.getTypeReference(), initializer) + } + else -> true } - return valueParameters.isNotEmpty() && valueParameters.none { it.typeReference == null } } } } diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/RemovePsiElementSimpleFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/RemovePsiElementSimpleFix.kt index 97387eaf170..e76f4af9e40 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/RemovePsiElementSimpleFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/RemovePsiElementSimpleFix.kt @@ -68,7 +68,7 @@ open class RemovePsiElementSimpleFix(element: PsiElement, private val text: Stri object RemoveVariableFactory : KotlinSingleIntentionActionFactory() { public override fun createAction(diagnostic: Diagnostic): KotlinQuickFixAction? { val expression = diagnostic.psiElement.getNonStrictParentOfType() ?: return null - if (!RemoveExplicitTypeIntention.redundantTypeSpecification(expression, expression.initializer)) return null + if (!RemoveExplicitTypeIntention.redundantTypeSpecification(expression.typeReference, expression.initializer)) return null return object : RemovePsiElementSimpleFix(expression, "Remove variable '${expression.name}'") { override fun invoke(project: Project, editor: Editor?, file: KtFile) { val initializer = expression.initializer diff --git a/idea/testData/intentions/removeExplicitType/lambdaInitializerWithAlias.kt b/idea/testData/intentions/removeExplicitType/lambdaInitializerWithAlias.kt new file mode 100644 index 00000000000..a47b3897976 --- /dev/null +++ b/idea/testData/intentions/removeExplicitType/lambdaInitializerWithAlias.kt @@ -0,0 +1,9 @@ +// IS_APPLICABLE: false + +typealias ValidationRule2 = (String, String) -> String +typealias ValidationRule3 = ValidationRule2 +typealias ValidationRule4 = ValidationRule3 + +fun getValidator(): ValidationRule4 = { text, eventType -> + "abc" +} \ No newline at end of file diff --git a/idea/testData/intentions/removeExplicitType/lambdaInitializerWithAlias2.kt b/idea/testData/intentions/removeExplicitType/lambdaInitializerWithAlias2.kt new file mode 100644 index 00000000000..8664bb28297 --- /dev/null +++ b/idea/testData/intentions/removeExplicitType/lambdaInitializerWithAlias2.kt @@ -0,0 +1,5 @@ +typealias ValidationRule2 = String +typealias ValidationRule3 = ValidationRule2 +typealias ValidationRule4 = ValidationRule3 + +fun getValidator(): ValidationRule4 = "abc" \ No newline at end of file diff --git a/idea/testData/intentions/removeExplicitType/lambdaInitializerWithAlias2.kt.after b/idea/testData/intentions/removeExplicitType/lambdaInitializerWithAlias2.kt.after new file mode 100644 index 00000000000..88bd53f05f8 --- /dev/null +++ b/idea/testData/intentions/removeExplicitType/lambdaInitializerWithAlias2.kt.after @@ -0,0 +1,5 @@ +typealias ValidationRule2 = String +typealias ValidationRule3 = ValidationRule2 +typealias ValidationRule4 = ValidationRule3 + +fun getValidator() = "abc" \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java index 1990ea85498..bc850ffed78 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java @@ -13367,6 +13367,16 @@ public class IntentionTestGenerated extends AbstractIntentionTest { runTest("idea/testData/intentions/removeExplicitType/lambdaInitializer5.kt"); } + @TestMetadata("lambdaInitializerWithAlias.kt") + public void testLambdaInitializerWithAlias() throws Exception { + runTest("idea/testData/intentions/removeExplicitType/lambdaInitializerWithAlias.kt"); + } + + @TestMetadata("lambdaInitializerWithAlias2.kt") + public void testLambdaInitializerWithAlias2() throws Exception { + runTest("idea/testData/intentions/removeExplicitType/lambdaInitializerWithAlias2.kt"); + } + @TestMetadata("needTypeArgument.kt") public void testNeedTypeArgument() throws Exception { runTest("idea/testData/intentions/removeExplicitType/needTypeArgument.kt");