From fdf9acfb6a3cbb6c07a0acf5e92d3017b3215765 Mon Sep 17 00:00:00 2001 From: Toshiaki Kameyama Date: Thu, 26 Sep 2019 12:21:14 +0300 Subject: [PATCH] Introduce subject to when: suggest for qualified, not for obj / constant #KT-18772 Fixed --- .../branchedTransformationUtils.kt | 21 ++++++++++++++++--- .../introduceWhenSubject/qualified.kt | 13 ++++++++++++ .../introduceWhenSubject/qualified.kt.after | 13 ++++++++++++ .../introduceWhenSubject/qualified2.kt | 13 ++++++++++++ .../introduceWhenSubject/qualified2.kt.after | 13 ++++++++++++ .../introduceWhenSubject/qualified3.kt | 11 ++++++++++ .../introduceWhenSubject/qualified3.kt.after | 11 ++++++++++ .../introduceWhenSubject/qualified4.kt | 14 +++++++++++++ .../introduceWhenSubject/qualified4.kt.after | 14 +++++++++++++ .../LocalInspectionTestGenerated.java | 20 ++++++++++++++++++ 10 files changed, 140 insertions(+), 3 deletions(-) create mode 100644 idea/testData/inspectionsLocal/branched/introduceWhenSubject/qualified.kt create mode 100644 idea/testData/inspectionsLocal/branched/introduceWhenSubject/qualified.kt.after create mode 100644 idea/testData/inspectionsLocal/branched/introduceWhenSubject/qualified2.kt create mode 100644 idea/testData/inspectionsLocal/branched/introduceWhenSubject/qualified2.kt.after create mode 100644 idea/testData/inspectionsLocal/branched/introduceWhenSubject/qualified3.kt create mode 100644 idea/testData/inspectionsLocal/branched/introduceWhenSubject/qualified3.kt.after create mode 100644 idea/testData/inspectionsLocal/branched/introduceWhenSubject/qualified4.kt create mode 100644 idea/testData/inspectionsLocal/branched/introduceWhenSubject/qualified4.kt.after diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/branchedTransformationUtils.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/branchedTransformationUtils.kt index 8e9d318f700..d039f58003d 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/branchedTransformationUtils.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/branchedTransformations/branchedTransformationUtils.kt @@ -6,6 +6,7 @@ package org.jetbrains.kotlin.idea.intentions.branchedTransformations import org.jetbrains.kotlin.idea.core.replaced +import org.jetbrains.kotlin.idea.references.mainReference import org.jetbrains.kotlin.idea.util.CommentSaver import org.jetbrains.kotlin.idea.util.psi.patternMatching.matches import org.jetbrains.kotlin.lexer.KtTokens @@ -48,7 +49,10 @@ fun KtWhenExpression.getSubjectToIntroduce(): KtExpression? { if (condition !is KtWhenConditionWithExpression) return null val candidate = condition.expression?.getWhenConditionSubjectCandidate() ?: return null - if (candidate !is KtNameReferenceExpression && candidate !is KtThisExpression) return null + if (candidate !is KtNameReferenceExpression + && (candidate as? KtQualifiedExpression)?.selectorExpression !is KtNameReferenceExpression + && candidate !is KtThisExpression + ) return null if (lastCandidate == null) { lastCandidate = candidate @@ -66,12 +70,14 @@ private fun KtExpression?.getWhenConditionSubjectCandidate(): KtExpression? = wh is KtBinaryExpression -> { val lhs = left + val rhs = right when (operationToken) { KtTokens.IN_KEYWORD, KtTokens.NOT_IN -> lhs - KtTokens.EQEQ -> lhs as? KtNameReferenceExpression ?: right + KtTokens.EQEQ -> + lhs?.takeIf { it.hasCandidateNameReferenceExpression() } ?: rhs?.takeIf { it.hasCandidateNameReferenceExpression() } KtTokens.OROR -> { val leftCandidate = lhs.getWhenConditionSubjectCandidate() - val rightCandidate = right.getWhenConditionSubjectCandidate() + val rightCandidate = rhs.getWhenConditionSubjectCandidate() if (leftCandidate.matches(rightCandidate)) leftCandidate else null } else -> null @@ -82,6 +88,15 @@ private fun KtExpression?.getWhenConditionSubjectCandidate(): KtExpression? = wh else -> null } +private fun KtExpression.hasCandidateNameReferenceExpression(): Boolean { + val nameReferenceExpression = this as? KtNameReferenceExpression + ?: (this as? KtQualifiedExpression)?.selectorExpression as? KtNameReferenceExpression + ?: return false + val resolved = nameReferenceExpression.mainReference.resolve() + if (resolved is KtObjectDeclaration || (resolved as? KtProperty)?.hasModifier(KtTokens.CONST_KEYWORD) == true) return false + return true +} + fun KtWhenExpression.introduceSubject(): KtWhenExpression? { val subject = getSubjectToIntroduce() ?: return null diff --git a/idea/testData/inspectionsLocal/branched/introduceWhenSubject/qualified.kt b/idea/testData/inspectionsLocal/branched/introduceWhenSubject/qualified.kt new file mode 100644 index 00000000000..a5ec6095185 --- /dev/null +++ b/idea/testData/inspectionsLocal/branched/introduceWhenSubject/qualified.kt @@ -0,0 +1,13 @@ +import Platform.JvmPlatform + +sealed class Platform { + object JvmPlatform : Platform() + class Another(val name: String) : Platform() +} + +class ModuleInfo(val platform: Platform) + +fun foo(moduleInfo: ModuleInfo) = when { + moduleInfo.platform == JvmPlatform -> 1 + else -> 0 +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/branched/introduceWhenSubject/qualified.kt.after b/idea/testData/inspectionsLocal/branched/introduceWhenSubject/qualified.kt.after new file mode 100644 index 00000000000..55b96d10164 --- /dev/null +++ b/idea/testData/inspectionsLocal/branched/introduceWhenSubject/qualified.kt.after @@ -0,0 +1,13 @@ +import Platform.JvmPlatform + +sealed class Platform { + object JvmPlatform : Platform() + class Another(val name: String) : Platform() +} + +class ModuleInfo(val platform: Platform) + +fun foo(moduleInfo: ModuleInfo) = when (moduleInfo.platform) { + JvmPlatform -> 1 + else -> 0 +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/branched/introduceWhenSubject/qualified2.kt b/idea/testData/inspectionsLocal/branched/introduceWhenSubject/qualified2.kt new file mode 100644 index 00000000000..5d6e94e8724 --- /dev/null +++ b/idea/testData/inspectionsLocal/branched/introduceWhenSubject/qualified2.kt @@ -0,0 +1,13 @@ +import Platform.JvmPlatform + +sealed class Platform { + object JvmPlatform : Platform() + class Another(val name: String) : Platform() +} + +class ModuleInfo(val platform: Platform) + +fun foo(moduleInfo: ModuleInfo) = when { + JvmPlatform == moduleInfo.platform -> 1 + else -> 0 +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/branched/introduceWhenSubject/qualified2.kt.after b/idea/testData/inspectionsLocal/branched/introduceWhenSubject/qualified2.kt.after new file mode 100644 index 00000000000..55b96d10164 --- /dev/null +++ b/idea/testData/inspectionsLocal/branched/introduceWhenSubject/qualified2.kt.after @@ -0,0 +1,13 @@ +import Platform.JvmPlatform + +sealed class Platform { + object JvmPlatform : Platform() + class Another(val name: String) : Platform() +} + +class ModuleInfo(val platform: Platform) + +fun foo(moduleInfo: ModuleInfo) = when (moduleInfo.platform) { + JvmPlatform -> 1 + else -> 0 +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/branched/introduceWhenSubject/qualified3.kt b/idea/testData/inspectionsLocal/branched/introduceWhenSubject/qualified3.kt new file mode 100644 index 00000000000..fa47bcc99f4 --- /dev/null +++ b/idea/testData/inspectionsLocal/branched/introduceWhenSubject/qualified3.kt @@ -0,0 +1,11 @@ +class Foo { + val bar = 1 +} + +fun test(foo: Foo): Int { + return when { + foo.bar == 1 -> 10 + foo.bar == 2 -> 20 + else -> 30 + } +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/branched/introduceWhenSubject/qualified3.kt.after b/idea/testData/inspectionsLocal/branched/introduceWhenSubject/qualified3.kt.after new file mode 100644 index 00000000000..a3edf21d139 --- /dev/null +++ b/idea/testData/inspectionsLocal/branched/introduceWhenSubject/qualified3.kt.after @@ -0,0 +1,11 @@ +class Foo { + val bar = 1 +} + +fun test(foo: Foo): Int { + return when (foo.bar) { + 1 -> 10 + 2 -> 20 + else -> 30 + } +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/branched/introduceWhenSubject/qualified4.kt b/idea/testData/inspectionsLocal/branched/introduceWhenSubject/qualified4.kt new file mode 100644 index 00000000000..f18451b1ba7 --- /dev/null +++ b/idea/testData/inspectionsLocal/branched/introduceWhenSubject/qualified4.kt @@ -0,0 +1,14 @@ +class Foo { + val bar = 1 +} + +const val A = 1 +const val B = 2 + +fun test(foo: Foo): Int { + return when { + A == foo.bar -> 10 + B == foo.bar -> 20 + else -> 30 + } +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/branched/introduceWhenSubject/qualified4.kt.after b/idea/testData/inspectionsLocal/branched/introduceWhenSubject/qualified4.kt.after new file mode 100644 index 00000000000..162cd3abe57 --- /dev/null +++ b/idea/testData/inspectionsLocal/branched/introduceWhenSubject/qualified4.kt.after @@ -0,0 +1,14 @@ +class Foo { + val bar = 1 +} + +const val A = 1 +const val B = 2 + +fun test(foo: Foo): Int { + return when (foo.bar) { + A -> 10 + B -> 20 + else -> 30 + } +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java index fd2aab99467..1d3a93c964c 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java @@ -824,6 +824,26 @@ public class LocalInspectionTestGenerated extends AbstractLocalInspectionTest { runTest("idea/testData/inspectionsLocal/branched/introduceWhenSubject/lineBreaksAndComments.kt"); } + @TestMetadata("qualified.kt") + public void testQualified() throws Exception { + runTest("idea/testData/inspectionsLocal/branched/introduceWhenSubject/qualified.kt"); + } + + @TestMetadata("qualified2.kt") + public void testQualified2() throws Exception { + runTest("idea/testData/inspectionsLocal/branched/introduceWhenSubject/qualified2.kt"); + } + + @TestMetadata("qualified3.kt") + public void testQualified3() throws Exception { + runTest("idea/testData/inspectionsLocal/branched/introduceWhenSubject/qualified3.kt"); + } + + @TestMetadata("qualified4.kt") + public void testQualified4() throws Exception { + runTest("idea/testData/inspectionsLocal/branched/introduceWhenSubject/qualified4.kt"); + } + @TestMetadata("this.kt") public void testThis() throws Exception { runTest("idea/testData/inspectionsLocal/branched/introduceWhenSubject/this.kt");