Redundant qualifier name: don't report for EnumClass.values/EnumClass.valueOf

#KT-34696 Fixed
This commit is contained in:
Toshiaki Kameyama
2020-01-27 05:10:56 +01:00
committed by Vladimir Dolzhenko
parent 611c4fe052
commit f747f8543e
4 changed files with 50 additions and 3 deletions
@@ -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<KtEnumEntry>()
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<KtClass>()) 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())
@@ -0,0 +1,13 @@
// PROBLEM: none
// WITH_RUNTIME
package packageName
import packageName.MyEnum.*
enum class MyEnum {
A, B, C, D, E;
}
fun main() {
<caret>MyEnum.valueOf("A")
}
@@ -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 <caret>MyEnum.values()) {
}
}
@@ -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");