Fix false positive "Redundant qualifier name" for functions with a receiver
#KT-30879 Fixed
This commit is contained in:
+10
-5
@@ -30,14 +30,15 @@ class RemoveRedundantQualifierNameInspection : AbstractKotlinInspection(), Clean
|
|||||||
object : KtVisitorVoid() {
|
object : KtVisitorVoid() {
|
||||||
override fun visitDotQualifiedExpression(expression: KtDotQualifiedExpression) {
|
override fun visitDotQualifiedExpression(expression: KtDotQualifiedExpression) {
|
||||||
if (expression.parent is KtDotQualifiedExpression? || expression.isInImportDirective()) return
|
if (expression.parent is KtDotQualifiedExpression? || expression.isInImportDirective()) return
|
||||||
|
val expressionForAnalyze = expression.firstExpressionWithoutReceiver() ?: return
|
||||||
|
|
||||||
val context = expression.analyze()
|
val context = expressionForAnalyze.analyze()
|
||||||
val importableFqName = expression.getQualifiedElementSelector()
|
val importableFqName = expressionForAnalyze.getQualifiedElementSelector()
|
||||||
?.getResolvedCall(context)?.resultingDescriptor
|
?.mainReference?.resolveToDescriptors(context)?.firstOrNull()
|
||||||
?.importableFqName ?: return
|
?.importableFqName ?: return
|
||||||
|
|
||||||
val applicableExpression = expression.firstApplicableExpression(validator = {
|
val applicableExpression = expressionForAnalyze.firstApplicableExpression(validator = {
|
||||||
applicableExpression(expression, context, importableFqName)
|
applicableExpression(expressionForAnalyze, context, importableFqName)
|
||||||
}) {
|
}) {
|
||||||
firstChild as? KtDotQualifiedExpression
|
firstChild as? KtDotQualifiedExpression
|
||||||
} ?: return
|
} ?: return
|
||||||
@@ -57,6 +58,10 @@ class RemoveRedundantQualifierNameInspection : AbstractKotlinInspection(), Clean
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private tailrec fun KtDotQualifiedExpression.firstExpressionWithoutReceiver(): KtDotQualifiedExpression? =
|
||||||
|
if ((getQualifiedElementSelector()?.mainReference?.resolve() as? KtFunction)?.receiverTypeReference == null) this
|
||||||
|
else (receiverExpression as? KtDotQualifiedExpression)?.firstExpressionWithoutReceiver()
|
||||||
|
|
||||||
private tailrec fun <T : KtElement> T.firstApplicableExpression(validator: T.() -> T?, generator: T.() -> T?): T? =
|
private tailrec fun <T : KtElement> T.firstApplicableExpression(validator: T.() -> T?, generator: T.() -> T?): T? =
|
||||||
validator() ?: generator()?.firstApplicableExpression(validator, generator)
|
validator() ?: generator()?.firstApplicableExpression(validator, generator)
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
import B.G
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
<caret>B.G.let { it }
|
||||||
|
}
|
||||||
|
|
||||||
|
class B {
|
||||||
|
object G
|
||||||
|
}
|
||||||
|
|
||||||
|
class C {
|
||||||
|
object G
|
||||||
|
}
|
||||||
+15
@@ -0,0 +1,15 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
import B.G
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
G.let { it }
|
||||||
|
}
|
||||||
|
|
||||||
|
class B {
|
||||||
|
object G
|
||||||
|
}
|
||||||
|
|
||||||
|
class C {
|
||||||
|
object G
|
||||||
|
}
|
||||||
+16
@@ -0,0 +1,16 @@
|
|||||||
|
// PROBLEM: none
|
||||||
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
import C.G
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
<caret>B.G.let { it }
|
||||||
|
}
|
||||||
|
|
||||||
|
class B {
|
||||||
|
object G
|
||||||
|
}
|
||||||
|
|
||||||
|
class C {
|
||||||
|
object G
|
||||||
|
}
|
||||||
+10
@@ -6230,6 +6230,11 @@ public class LocalInspectionTestGenerated extends AbstractLocalInspectionTest {
|
|||||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/inspectionsLocal/removeRedundantQualifierName"), Pattern.compile("^([\\w\\-_]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/inspectionsLocal/removeRedundantQualifierName"), Pattern.compile("^([\\w\\-_]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("asReceiver.kt")
|
||||||
|
public void testAsReceiver() throws Exception {
|
||||||
|
runTest("idea/testData/inspectionsLocal/removeRedundantQualifierName/asReceiver.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("companionCollision.kt")
|
@TestMetadata("companionCollision.kt")
|
||||||
public void testCompanionCollision() throws Exception {
|
public void testCompanionCollision() throws Exception {
|
||||||
runTest("idea/testData/inspectionsLocal/removeRedundantQualifierName/companionCollision.kt");
|
runTest("idea/testData/inspectionsLocal/removeRedundantQualifierName/companionCollision.kt");
|
||||||
@@ -6350,6 +6355,11 @@ public class LocalInspectionTestGenerated extends AbstractLocalInspectionTest {
|
|||||||
runTest("idea/testData/inspectionsLocal/removeRedundantQualifierName/localFun2.kt");
|
runTest("idea/testData/inspectionsLocal/removeRedundantQualifierName/localFun2.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("notApplicableAsReceiver.kt")
|
||||||
|
public void testNotApplicableAsReceiver() throws Exception {
|
||||||
|
runTest("idea/testData/inspectionsLocal/removeRedundantQualifierName/notApplicableAsReceiver.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("notApplicableCollisionTopLevelClass.kt")
|
@TestMetadata("notApplicableCollisionTopLevelClass.kt")
|
||||||
public void testNotApplicableCollisionTopLevelClass() throws Exception {
|
public void testNotApplicableCollisionTopLevelClass() throws Exception {
|
||||||
runTest("idea/testData/inspectionsLocal/removeRedundantQualifierName/notApplicableCollisionTopLevelClass.kt");
|
runTest("idea/testData/inspectionsLocal/removeRedundantQualifierName/notApplicableCollisionTopLevelClass.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user