Redundant qualifier name: don't report for EnumClass.Companion

#KT-37181 Fixed
This commit is contained in:
Toshiaki Kameyama
2020-03-12 04:14:18 +01:00
committed by Vladimir Dolzhenko
parent f747f8543e
commit 831fbba0c1
5 changed files with 77 additions and 3 deletions
@@ -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<KtQualifiedExpression>()?.receiverExpression ?: it
}.mainReference?.resolve()
val parentEnumEntry = expressionForAnalyze.getStrictParentOfType<KtEnumEntry>()
if (parentEnumEntry != null) {
val companionObject = (receiverReference as? KtObjectDeclaration)?.takeIf { it.isCompanion() }
if (companionObject?.containingClass() == parentEnumEntry.getStrictParentOfType<KtClass>()) return
}
if ((receiverReference as? KtClass)?.isEnum() == true
if (receiverReference?.safeAs<KtClass>()?.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<KtDotQualifiedExpression>()?.selectorExpression ?: selectorExpression
return selector?.referenceExpression()?.mainReference?.resolve()?.safeAs<KtObjectDeclaration>()?.isCompanion() == true
}
}
private tailrec fun KtDotQualifiedExpression.firstExpressionWithoutReceiver(): KtDotQualifiedExpression? = if (hasNotReceiver())
@@ -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() {
<caret>MyEnum.Companion::baz
}
@@ -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() {
<caret>MyEnum.O::baz
}
@@ -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() {
<caret>MyEnum.Companion.baz()
}
@@ -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");