diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/RemoveRedundantQualifierNameInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/RemoveRedundantQualifierNameInspection.kt index 9bbcfa4919b..1d50bc5da18 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/RemoveRedundantQualifierNameInspection.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/RemoveRedundantQualifierNameInspection.kt @@ -6,13 +6,16 @@ package org.jetbrains.kotlin.idea.inspections import com.intellij.codeInspection.* +import com.intellij.lang.jvm.JvmModifier import com.intellij.openapi.project.Project import com.intellij.openapi.util.TextRange import com.intellij.psi.PsiElementVisitor +import com.intellij.psi.PsiMember import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.idea.analysis.analyzeAsReplacement 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.references.mainReference import org.jetbrains.kotlin.idea.util.getResolutionScope @@ -65,9 +68,13 @@ class RemoveRedundantQualifierNameInspection : AbstractKotlinInspection(), Clean } } -private tailrec fun KtDotQualifiedExpression.firstExpressionWithoutReceiver(): KtDotQualifiedExpression? = - if ((getQualifiedElementSelector()?.mainReference?.resolve() as? KtCallableDeclaration)?.receiverTypeReference == null) this - else (receiverExpression as? KtDotQualifiedExpression)?.firstExpressionWithoutReceiver() +private tailrec fun KtDotQualifiedExpression.firstExpressionWithoutReceiver(): KtDotQualifiedExpression? { + val element = getQualifiedElementSelector()?.mainReference?.resolve() ?: return null + return if (element is KtClassOrObject || + element is KtCallableDeclaration && element.receiverTypeReference == null || + element is PsiMember && element.hasModifier(JvmModifier.STATIC) + ) this else (receiverExpression as? KtDotQualifiedExpression)?.firstExpressionWithoutReceiver() +} private tailrec fun T.firstApplicableExpression(validator: T.() -> T?, generator: T.() -> T?): T? = validator() ?: generator()?.firstApplicableExpression(validator, generator) @@ -90,10 +97,11 @@ private fun KtDotQualifiedExpression.applicableExpression( ?.firstOrNull() ?: return null return takeIf { - if (newDescriptor is ImportedFromObjectCallableDescriptor<*>) - originalDescriptor == newDescriptor.callableFromObject - else - originalDescriptor == newDescriptor + originalDescriptor.importableFqName == newDescriptor.importableFqName && + if (newDescriptor is ImportedFromObjectCallableDescriptor<*>) + compareDescriptors(project, newDescriptor.callableFromObject, originalDescriptor) + else + compareDescriptors(project, newDescriptor, originalDescriptor) } } diff --git a/idea/testData/multiFileLocalInspections/redundantQualifierName/javaStatic/after/my/Reproducer.java b/idea/testData/multiFileLocalInspections/redundantQualifierName/javaStatic/after/my/Reproducer.java new file mode 100644 index 00000000000..07583fa057b --- /dev/null +++ b/idea/testData/multiFileLocalInspections/redundantQualifierName/javaStatic/after/my/Reproducer.java @@ -0,0 +1,11 @@ +package my; + +public class Reproducer { + public static Reproducer test() { + return new Reproducer(); + } + + public int number() { + return 42; + } +} \ No newline at end of file diff --git a/idea/testData/multiFileLocalInspections/redundantQualifierName/javaStatic/after/test.kt b/idea/testData/multiFileLocalInspections/redundantQualifierName/javaStatic/after/test.kt new file mode 100644 index 00000000000..00716e34b91 --- /dev/null +++ b/idea/testData/multiFileLocalInspections/redundantQualifierName/javaStatic/after/test.kt @@ -0,0 +1,9 @@ +package my.simple.name + +import my.Reproducer + +fun test() = Reproducer() + +fun main() { + Reproducer.test().number() +} \ No newline at end of file diff --git a/idea/testData/multiFileLocalInspections/redundantQualifierName/javaStatic/before/my/Reproducer.java b/idea/testData/multiFileLocalInspections/redundantQualifierName/javaStatic/before/my/Reproducer.java new file mode 100644 index 00000000000..07583fa057b --- /dev/null +++ b/idea/testData/multiFileLocalInspections/redundantQualifierName/javaStatic/before/my/Reproducer.java @@ -0,0 +1,11 @@ +package my; + +public class Reproducer { + public static Reproducer test() { + return new Reproducer(); + } + + public int number() { + return 42; + } +} \ No newline at end of file diff --git a/idea/testData/multiFileLocalInspections/redundantQualifierName/javaStatic/before/test.kt b/idea/testData/multiFileLocalInspections/redundantQualifierName/javaStatic/before/test.kt new file mode 100644 index 00000000000..964224f7044 --- /dev/null +++ b/idea/testData/multiFileLocalInspections/redundantQualifierName/javaStatic/before/test.kt @@ -0,0 +1,9 @@ +package my.simple.name + +import my.Reproducer + +fun test() = Reproducer() + +fun main() { + Reproducer.test().number() +} \ No newline at end of file diff --git a/idea/testData/multiFileLocalInspections/redundantQualifierName/javaStatic/fromKotlinTest.test b/idea/testData/multiFileLocalInspections/redundantQualifierName/javaStatic/fromKotlinTest.test new file mode 100644 index 00000000000..4bca2ef4758 --- /dev/null +++ b/idea/testData/multiFileLocalInspections/redundantQualifierName/javaStatic/fromKotlinTest.test @@ -0,0 +1,5 @@ +{ + "inspectionClass": "org.jetbrains.kotlin.idea.inspections.RemoveRedundantQualifierNameInspection", + "problem": "none", + "mainFile": "test.kt" +} \ No newline at end of file diff --git a/idea/testData/multiFileLocalInspections/redundantQualifierName/javaStatic2/after/my/Reproducer.java b/idea/testData/multiFileLocalInspections/redundantQualifierName/javaStatic2/after/my/Reproducer.java new file mode 100644 index 00000000000..07583fa057b --- /dev/null +++ b/idea/testData/multiFileLocalInspections/redundantQualifierName/javaStatic2/after/my/Reproducer.java @@ -0,0 +1,11 @@ +package my; + +public class Reproducer { + public static Reproducer test() { + return new Reproducer(); + } + + public int number() { + return 42; + } +} \ No newline at end of file diff --git a/idea/testData/multiFileLocalInspections/redundantQualifierName/javaStatic2/after/test.kt b/idea/testData/multiFileLocalInspections/redundantQualifierName/javaStatic2/after/test.kt new file mode 100644 index 00000000000..a08b251fc91 --- /dev/null +++ b/idea/testData/multiFileLocalInspections/redundantQualifierName/javaStatic2/after/test.kt @@ -0,0 +1,10 @@ +package my.simple.name + +import my.Reproducer +import my.Reproducer.test + +fun test() = Reproducer() + +fun main() { + test().number() +} \ No newline at end of file diff --git a/idea/testData/multiFileLocalInspections/redundantQualifierName/javaStatic2/before/my/Reproducer.java b/idea/testData/multiFileLocalInspections/redundantQualifierName/javaStatic2/before/my/Reproducer.java new file mode 100644 index 00000000000..07583fa057b --- /dev/null +++ b/idea/testData/multiFileLocalInspections/redundantQualifierName/javaStatic2/before/my/Reproducer.java @@ -0,0 +1,11 @@ +package my; + +public class Reproducer { + public static Reproducer test() { + return new Reproducer(); + } + + public int number() { + return 42; + } +} \ No newline at end of file diff --git a/idea/testData/multiFileLocalInspections/redundantQualifierName/javaStatic2/before/test.kt b/idea/testData/multiFileLocalInspections/redundantQualifierName/javaStatic2/before/test.kt new file mode 100644 index 00000000000..9db30a65e1c --- /dev/null +++ b/idea/testData/multiFileLocalInspections/redundantQualifierName/javaStatic2/before/test.kt @@ -0,0 +1,10 @@ +package my.simple.name + +import my.Reproducer +import my.Reproducer.test + +fun test() = Reproducer() + +fun main() { + Reproducer.test().number() +} \ No newline at end of file diff --git a/idea/testData/multiFileLocalInspections/redundantQualifierName/javaStatic2/fromKotlinTest.test b/idea/testData/multiFileLocalInspections/redundantQualifierName/javaStatic2/fromKotlinTest.test new file mode 100644 index 00000000000..dc6b7c5047a --- /dev/null +++ b/idea/testData/multiFileLocalInspections/redundantQualifierName/javaStatic2/fromKotlinTest.test @@ -0,0 +1,4 @@ +{ + "inspectionClass": "org.jetbrains.kotlin.idea.inspections.RemoveRedundantQualifierNameInspection", + "mainFile": "test.kt" +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/inspections/MultiFileLocalInspectionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/inspections/MultiFileLocalInspectionTestGenerated.java index fcd6d6f9ea2..d8e9d1c7dd6 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/inspections/MultiFileLocalInspectionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/inspections/MultiFileLocalInspectionTestGenerated.java @@ -89,6 +89,16 @@ public class MultiFileLocalInspectionTestGenerated extends AbstractMultiFileLoca runTest("idea/testData/multiFileLocalInspections/reconcilePackageWithDirectory/packageMatchesDirectory/packageMatchesDirectory.test"); } + @TestMetadata("redundantQualifierName/javaStatic2/fromKotlinTest.test") + public void testRedundantQualifierName_javaStatic2_FromKotlinTest() throws Exception { + runTest("idea/testData/multiFileLocalInspections/redundantQualifierName/javaStatic2/fromKotlinTest.test"); + } + + @TestMetadata("redundantQualifierName/javaStatic/fromKotlinTest.test") + public void testRedundantQualifierName_javaStatic_FromKotlinTest() throws Exception { + runTest("idea/testData/multiFileLocalInspections/redundantQualifierName/javaStatic/fromKotlinTest.test"); + } + @TestMetadata("unusedSymbol/fromKotlinTest/fromKotlinTest.test") public void testUnusedSymbol_fromKotlinTest_FromKotlinTest() throws Exception { runTest("idea/testData/multiFileLocalInspections/unusedSymbol/fromKotlinTest/fromKotlinTest.test");