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");