Redundant qualifier name: don't report for EnumClass.values/EnumClass.valueOf
#KT-34696 Fixed
This commit is contained in:
committed by
Vladimir Dolzhenko
parent
611c4fe052
commit
f747f8543e
+13
-3
@@ -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.ShortenReferences
|
||||||
import org.jetbrains.kotlin.idea.core.compareDescriptors
|
import org.jetbrains.kotlin.idea.core.compareDescriptors
|
||||||
import org.jetbrains.kotlin.idea.imports.importableFqName
|
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.references.mainReference
|
||||||
import org.jetbrains.kotlin.idea.search.usagesSearch.descriptor
|
|
||||||
import org.jetbrains.kotlin.idea.util.getResolutionScope
|
import org.jetbrains.kotlin.idea.util.getResolutionScope
|
||||||
import org.jetbrains.kotlin.idea.util.hasNotReceiver
|
import org.jetbrains.kotlin.idea.util.hasNotReceiver
|
||||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
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
|
import org.jetbrains.kotlin.resolve.scopes.utils.findFirstClassifierWithDeprecationStatus
|
||||||
|
|
||||||
class RemoveRedundantQualifierNameInspection : AbstractKotlinInspection(), CleanupLocalInspectionTool {
|
class RemoveRedundantQualifierNameInspection : AbstractKotlinInspection(), CleanupLocalInspectionTool {
|
||||||
|
companion object {
|
||||||
|
private val ENUM_STATIC_METHODS = listOf("values", "valueOf")
|
||||||
|
}
|
||||||
|
|
||||||
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor =
|
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor =
|
||||||
object : KtVisitorVoid() {
|
object : KtVisitorVoid() {
|
||||||
override fun visitDotQualifiedExpression(expression: KtDotQualifiedExpression) {
|
override fun visitDotQualifiedExpression(expression: KtDotQualifiedExpression) {
|
||||||
@@ -44,12 +48,16 @@ class RemoveRedundantQualifierNameInspection : AbstractKotlinInspection(), Clean
|
|||||||
else
|
else
|
||||||
expressionForAnalyze
|
expressionForAnalyze
|
||||||
|
|
||||||
|
val receiverReference = expressionForAnalyze.receiverExpression.mainReference?.resolve()
|
||||||
val parentEnumEntry = expressionForAnalyze.getStrictParentOfType<KtEnumEntry>()
|
val parentEnumEntry = expressionForAnalyze.getStrictParentOfType<KtEnumEntry>()
|
||||||
if (parentEnumEntry != null) {
|
if (parentEnumEntry != null) {
|
||||||
val companionObject = (expressionForAnalyze.receiverExpression.mainReference?.resolve() as? KtObjectDeclaration)
|
val companionObject = (receiverReference as? KtObjectDeclaration)?.takeIf { it.isCompanion() }
|
||||||
?.takeIf { it.isCompanion() }
|
|
||||||
if (companionObject?.containingClass() == parentEnumEntry.getStrictParentOfType<KtClass>()) return
|
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()
|
val context = originalExpression.analyze()
|
||||||
|
|
||||||
@@ -77,6 +85,8 @@ class RemoveRedundantQualifierNameInspection : AbstractKotlinInspection(), Clean
|
|||||||
reportProblem(holder, applicableExpression)
|
reportProblem(holder, applicableExpression)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun KtDotQualifiedExpression.isEnumStaticMethodCall() = callExpression?.calleeExpression?.text in ENUM_STATIC_METHODS
|
||||||
}
|
}
|
||||||
|
|
||||||
private tailrec fun KtDotQualifiedExpression.firstExpressionWithoutReceiver(): KtDotQualifiedExpression? = if (hasNotReceiver())
|
private tailrec fun KtDotQualifiedExpression.firstExpressionWithoutReceiver(): KtDotQualifiedExpression? = if (hasNotReceiver())
|
||||||
|
|||||||
+13
@@ -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")
|
||||||
|
}
|
||||||
+14
@@ -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()) {
|
||||||
|
}
|
||||||
|
}
|
||||||
+10
@@ -9107,6 +9107,16 @@ public class LocalInspectionTestGenerated extends AbstractLocalInspectionTest {
|
|||||||
runTest("idea/testData/inspectionsLocal/removeRedundantQualifierName/notApplicableEnumInEnum2.kt");
|
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")
|
@TestMetadata("notApplicableExpression.kt")
|
||||||
public void testNotApplicableExpression() throws Exception {
|
public void testNotApplicableExpression() throws Exception {
|
||||||
runTest("idea/testData/inspectionsLocal/removeRedundantQualifierName/notApplicableExpression.kt");
|
runTest("idea/testData/inspectionsLocal/removeRedundantQualifierName/notApplicableExpression.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user