From 831fbba0c1e17767831890d0963bd5d34708f0fe Mon Sep 17 00:00:00 2001 From: Toshiaki Kameyama Date: Thu, 12 Mar 2020 04:14:18 +0100 Subject: [PATCH] Redundant qualifier name: don't report for EnumClass.Companion #KT-37181 Fixed --- .../RemoveRedundantQualifierNameInspection.kt | 14 +++++++++++--- .../notApplicableEnumCompanion.kt | 17 +++++++++++++++++ .../notApplicableEnumCompanion2.kt | 17 +++++++++++++++++ .../notApplicableEnumCompanion3.kt | 17 +++++++++++++++++ .../LocalInspectionTestGenerated.java | 15 +++++++++++++++ 5 files changed, 77 insertions(+), 3 deletions(-) create mode 100644 idea/testData/inspectionsLocal/removeRedundantQualifierName/notApplicableEnumCompanion.kt create mode 100644 idea/testData/inspectionsLocal/removeRedundantQualifierName/notApplicableEnumCompanion2.kt create mode 100644 idea/testData/inspectionsLocal/removeRedundantQualifierName/notApplicableEnumCompanion3.kt diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/RemoveRedundantQualifierNameInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/RemoveRedundantQualifierNameInspection.kt index 1923dea1837..38788eb7e86 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/RemoveRedundantQualifierNameInspection.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/RemoveRedundantQualifierNameInspection.kt @@ -29,6 +29,7 @@ import org.jetbrains.kotlin.resolve.ImportedFromObjectCallableDescriptor import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe import org.jetbrains.kotlin.resolve.descriptorUtil.isCompanionObject import org.jetbrains.kotlin.resolve.scopes.utils.findFirstClassifierWithDeprecationStatus +import org.jetbrains.kotlin.utils.addToStdlib.safeAs class RemoveRedundantQualifierNameInspection : AbstractKotlinInspection(), CleanupLocalInspectionTool { companion object { @@ -48,15 +49,17 @@ class RemoveRedundantQualifierNameInspection : AbstractKotlinInspection(), Clean else expressionForAnalyze - val receiverReference = expressionForAnalyze.receiverExpression.mainReference?.resolve() + val receiverReference = expressionForAnalyze.receiverExpression.let { + it.safeAs()?.receiverExpression ?: it + }.mainReference?.resolve() val parentEnumEntry = expressionForAnalyze.getStrictParentOfType() if (parentEnumEntry != null) { val companionObject = (receiverReference as? KtObjectDeclaration)?.takeIf { it.isCompanion() } if (companionObject?.containingClass() == parentEnumEntry.getStrictParentOfType()) return } - if ((receiverReference as? KtClass)?.isEnum() == true + if (receiverReference?.safeAs()?.isEnum() == true && expressionForAnalyze.getParentOfTypesAndPredicate(true, KtClass::class.java) { it.isEnum() } != receiverReference - && expressionForAnalyze.isEnumStaticMethodCall() + && (expressionForAnalyze.isEnumStaticMethodCall() || expressionForAnalyze.isCompanionObjectReference()) ) return val context = originalExpression.analyze() @@ -87,6 +90,11 @@ class RemoveRedundantQualifierNameInspection : AbstractKotlinInspection(), Clean } private fun KtDotQualifiedExpression.isEnumStaticMethodCall() = callExpression?.calleeExpression?.text in ENUM_STATIC_METHODS + + private fun KtDotQualifiedExpression.isCompanionObjectReference(): Boolean { + val selector = receiverExpression.safeAs()?.selectorExpression ?: selectorExpression + return selector?.referenceExpression()?.mainReference?.resolve()?.safeAs()?.isCompanion() == true + } } private tailrec fun KtDotQualifiedExpression.firstExpressionWithoutReceiver(): KtDotQualifiedExpression? = if (hasNotReceiver()) diff --git a/idea/testData/inspectionsLocal/removeRedundantQualifierName/notApplicableEnumCompanion.kt b/idea/testData/inspectionsLocal/removeRedundantQualifierName/notApplicableEnumCompanion.kt new file mode 100644 index 00000000000..248d5613768 --- /dev/null +++ b/idea/testData/inspectionsLocal/removeRedundantQualifierName/notApplicableEnumCompanion.kt @@ -0,0 +1,17 @@ +// PROBLEM: none +package foo.bar + +import foo.bar.MyEnum.* + +enum class MyEnum(val id: Int) { + A(1), + B(2); + + companion object { + fun baz() = "" + } +} + +fun test() { + MyEnum.Companion::baz +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/removeRedundantQualifierName/notApplicableEnumCompanion2.kt b/idea/testData/inspectionsLocal/removeRedundantQualifierName/notApplicableEnumCompanion2.kt new file mode 100644 index 00000000000..93094358b5a --- /dev/null +++ b/idea/testData/inspectionsLocal/removeRedundantQualifierName/notApplicableEnumCompanion2.kt @@ -0,0 +1,17 @@ +// PROBLEM: none +package foo.bar + +import foo.bar.MyEnum.* + +enum class MyEnum(val id: Int) { + A(1), + B(2); + + companion object O { + fun baz() = "" + } +} + +fun test() { + MyEnum.O::baz +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/removeRedundantQualifierName/notApplicableEnumCompanion3.kt b/idea/testData/inspectionsLocal/removeRedundantQualifierName/notApplicableEnumCompanion3.kt new file mode 100644 index 00000000000..732e7d89daf --- /dev/null +++ b/idea/testData/inspectionsLocal/removeRedundantQualifierName/notApplicableEnumCompanion3.kt @@ -0,0 +1,17 @@ +// PROBLEM: none +package foo.bar + +import foo.bar.MyEnum.* + +enum class MyEnum(val id: Int) { + A(1), + B(2); + + companion object { + fun baz() = "" + } +} + +fun test() { + MyEnum.Companion.baz() +} \ 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 963115456ff..a542e6633f9 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java @@ -9082,6 +9082,21 @@ public class LocalInspectionTestGenerated extends AbstractLocalInspectionTest { runTest("idea/testData/inspectionsLocal/removeRedundantQualifierName/notApplicableCompanionType2.kt"); } + @TestMetadata("notApplicableEnumCompanion.kt") + public void testNotApplicableEnumCompanion() throws Exception { + runTest("idea/testData/inspectionsLocal/removeRedundantQualifierName/notApplicableEnumCompanion.kt"); + } + + @TestMetadata("notApplicableEnumCompanion2.kt") + public void testNotApplicableEnumCompanion2() throws Exception { + runTest("idea/testData/inspectionsLocal/removeRedundantQualifierName/notApplicableEnumCompanion2.kt"); + } + + @TestMetadata("notApplicableEnumCompanion3.kt") + public void testNotApplicableEnumCompanion3() throws Exception { + runTest("idea/testData/inspectionsLocal/removeRedundantQualifierName/notApplicableEnumCompanion3.kt"); + } + @TestMetadata("notApplicableEnumEntry.kt") public void testNotApplicableEnumEntry() throws Exception { runTest("idea/testData/inspectionsLocal/removeRedundantQualifierName/notApplicableEnumEntry.kt");