diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/RemoveRedundantQualifierNameInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/RemoveRedundantQualifierNameInspection.kt index b79071364df..1923dea1837 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/RemoveRedundantQualifierNameInspection.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/RemoveRedundantQualifierNameInspection.kt @@ -17,8 +17,8 @@ import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.core.ShortenReferences import org.jetbrains.kotlin.idea.core.compareDescriptors import org.jetbrains.kotlin.idea.imports.importableFqName +import org.jetbrains.kotlin.idea.intentions.callExpression import org.jetbrains.kotlin.idea.references.mainReference -import org.jetbrains.kotlin.idea.search.usagesSearch.descriptor import org.jetbrains.kotlin.idea.util.getResolutionScope import org.jetbrains.kotlin.idea.util.hasNotReceiver import org.jetbrains.kotlin.incremental.components.NoLookupLocation @@ -31,6 +31,10 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.isCompanionObject import org.jetbrains.kotlin.resolve.scopes.utils.findFirstClassifierWithDeprecationStatus class RemoveRedundantQualifierNameInspection : AbstractKotlinInspection(), CleanupLocalInspectionTool { + companion object { + private val ENUM_STATIC_METHODS = listOf("values", "valueOf") + } + override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor = object : KtVisitorVoid() { override fun visitDotQualifiedExpression(expression: KtDotQualifiedExpression) { @@ -44,12 +48,16 @@ class RemoveRedundantQualifierNameInspection : AbstractKotlinInspection(), Clean else expressionForAnalyze + val receiverReference = expressionForAnalyze.receiverExpression.mainReference?.resolve() val parentEnumEntry = expressionForAnalyze.getStrictParentOfType() if (parentEnumEntry != null) { - val companionObject = (expressionForAnalyze.receiverExpression.mainReference?.resolve() as? KtObjectDeclaration) - ?.takeIf { it.isCompanion() } + val companionObject = (receiverReference as? KtObjectDeclaration)?.takeIf { it.isCompanion() } if (companionObject?.containingClass() == parentEnumEntry.getStrictParentOfType()) return } + if ((receiverReference as? KtClass)?.isEnum() == true + && expressionForAnalyze.getParentOfTypesAndPredicate(true, KtClass::class.java) { it.isEnum() } != receiverReference + && expressionForAnalyze.isEnumStaticMethodCall() + ) return val context = originalExpression.analyze() @@ -77,6 +85,8 @@ class RemoveRedundantQualifierNameInspection : AbstractKotlinInspection(), Clean reportProblem(holder, applicableExpression) } } + + private fun KtDotQualifiedExpression.isEnumStaticMethodCall() = callExpression?.calleeExpression?.text in ENUM_STATIC_METHODS } private tailrec fun KtDotQualifiedExpression.firstExpressionWithoutReceiver(): KtDotQualifiedExpression? = if (hasNotReceiver()) diff --git a/idea/testData/inspectionsLocal/removeRedundantQualifierName/notApplicableEnumValueOf.kt b/idea/testData/inspectionsLocal/removeRedundantQualifierName/notApplicableEnumValueOf.kt new file mode 100644 index 00000000000..3d886ff0576 --- /dev/null +++ b/idea/testData/inspectionsLocal/removeRedundantQualifierName/notApplicableEnumValueOf.kt @@ -0,0 +1,13 @@ +// PROBLEM: none +// WITH_RUNTIME +package packageName + +import packageName.MyEnum.* + +enum class MyEnum { + A, B, C, D, E; +} + +fun main() { + MyEnum.valueOf("A") +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/removeRedundantQualifierName/notApplicableEnumValues.kt b/idea/testData/inspectionsLocal/removeRedundantQualifierName/notApplicableEnumValues.kt new file mode 100644 index 00000000000..b458206c0c6 --- /dev/null +++ b/idea/testData/inspectionsLocal/removeRedundantQualifierName/notApplicableEnumValues.kt @@ -0,0 +1,14 @@ +// PROBLEM: none +// WITH_RUNTIME +package packageName + +import packageName.MyEnum.* + +enum class MyEnum { + A, B, C, D, E; +} + +fun main() { + for (value in MyEnum.values()) { + } +} \ 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 7bc7b207666..963115456ff 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java @@ -9107,6 +9107,16 @@ public class LocalInspectionTestGenerated extends AbstractLocalInspectionTest { runTest("idea/testData/inspectionsLocal/removeRedundantQualifierName/notApplicableEnumInEnum2.kt"); } + @TestMetadata("notApplicableEnumValueOf.kt") + public void testNotApplicableEnumValueOf() throws Exception { + runTest("idea/testData/inspectionsLocal/removeRedundantQualifierName/notApplicableEnumValueOf.kt"); + } + + @TestMetadata("notApplicableEnumValues.kt") + public void testNotApplicableEnumValues() throws Exception { + runTest("idea/testData/inspectionsLocal/removeRedundantQualifierName/notApplicableEnumValues.kt"); + } + @TestMetadata("notApplicableExpression.kt") public void testNotApplicableExpression() throws Exception { runTest("idea/testData/inspectionsLocal/removeRedundantQualifierName/notApplicableExpression.kt");