From 89180e2650d3638b1f17ffc870d099ddbd4e7de1 Mon Sep 17 00:00:00 2001 From: Toshiaki Kameyama Date: Thu, 3 Oct 2019 18:54:51 +0900 Subject: [PATCH] Redundant companion reference: fix false positive with Java synthetic property #KT-33771 Fixed --- .../RedundantCompanionReferenceInspection.kt | 21 +++++++++++++++++-- .../javaFakeGetter.1.java | 5 +++++ .../javaFakeGetter.1.java.after | 5 +++++ .../javaFakeGetter.kt | 9 ++++++++ .../javaFakeGetter.kt.after | 9 ++++++++ .../javaFakeSetter.1.java | 5 +++++ .../javaFakeSetter.1.java.after | 5 +++++ .../javaFakeSetter.kt | 9 ++++++++ .../javaFakeSetter.kt.after | 9 ++++++++ .../javaGetter.1.java | 5 +++++ .../redundantCompanionReference/javaGetter.kt | 11 ++++++++++ .../javaSetter.1.java | 4 ++++ .../redundantCompanionReference/javaSetter.kt | 11 ++++++++++ .../LocalInspectionTestGenerated.java | 20 ++++++++++++++++++ 14 files changed, 126 insertions(+), 2 deletions(-) create mode 100644 idea/testData/inspectionsLocal/redundantCompanionReference/javaFakeGetter.1.java create mode 100644 idea/testData/inspectionsLocal/redundantCompanionReference/javaFakeGetter.1.java.after create mode 100644 idea/testData/inspectionsLocal/redundantCompanionReference/javaFakeGetter.kt create mode 100644 idea/testData/inspectionsLocal/redundantCompanionReference/javaFakeGetter.kt.after create mode 100644 idea/testData/inspectionsLocal/redundantCompanionReference/javaFakeSetter.1.java create mode 100644 idea/testData/inspectionsLocal/redundantCompanionReference/javaFakeSetter.1.java.after create mode 100644 idea/testData/inspectionsLocal/redundantCompanionReference/javaFakeSetter.kt create mode 100644 idea/testData/inspectionsLocal/redundantCompanionReference/javaFakeSetter.kt.after create mode 100644 idea/testData/inspectionsLocal/redundantCompanionReference/javaGetter.1.java create mode 100644 idea/testData/inspectionsLocal/redundantCompanionReference/javaGetter.kt create mode 100644 idea/testData/inspectionsLocal/redundantCompanionReference/javaSetter.1.java create mode 100644 idea/testData/inspectionsLocal/redundantCompanionReference/javaSetter.kt diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/RedundantCompanionReferenceInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/RedundantCompanionReferenceInspection.kt index 41f32d4cd1f..0a7aa47fd98 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/RedundantCompanionReferenceInspection.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/RedundantCompanionReferenceInspection.kt @@ -17,6 +17,8 @@ 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.incremental.components.NoLookupLocation +import org.jetbrains.kotlin.load.java.JvmAbi +import org.jetbrains.kotlin.load.java.descriptors.JavaMethodDescriptor import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.containingClass @@ -29,6 +31,8 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassNotAny import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperInterfaces import org.jetbrains.kotlin.resolve.scopes.utils.findFunction import org.jetbrains.kotlin.resolve.scopes.utils.findVariable +import org.jetbrains.kotlin.types.typeUtil.isUnit +import org.jetbrains.kotlin.types.typeUtil.makeNotNullable class RedundantCompanionReferenceInspection : AbstractKotlinInspection() { override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor { @@ -60,11 +64,24 @@ class RedundantCompanionReferenceInspection : AbstractKotlinInspection() { val containingClass = objectDeclaration.containingClass() ?: return false if (reference.containingClass() != containingClass && reference == parent.receiverExpression) return false val containingClassDescriptor = containingClass.descriptor as? ClassDescriptor ?: return false - val selectorDescriptor = selectorExpression?.getResolvedCall(context)?.resultingDescriptor - when (selectorDescriptor) { + when (val selectorDescriptor = selectorExpression?.getResolvedCall(context)?.resultingDescriptor) { is PropertyDescriptor -> { val name = selectorDescriptor.name if (containingClassDescriptor.findMemberVariable(name) != null) return false + + val type = selectorDescriptor.type + val javaGetter = containingClassDescriptor.findMemberFunction( + Name.identifier(JvmAbi.getterName(name.asString())) + ) as? JavaMethodDescriptor + if (javaGetter?.valueParameters?.isEmpty() == true && javaGetter.returnType?.makeNotNullable() == type) return false + + val javaSetter = containingClassDescriptor.findMemberFunction( + Name.identifier(JvmAbi.setterName(name.asString())) + ) as? JavaMethodDescriptor + if (javaSetter?.valueParameters?.singleOrNull()?.type?.makeNotNullable() == type + && javaSetter.returnType?.makeNotNullable()?.isUnit() == true + ) return false + val variable = reference.getResolutionScope().findVariable(name, NoLookupLocation.FROM_IDE) if (variable != null && variable.isLocalOrExtension(containingClassDescriptor)) return false } diff --git a/idea/testData/inspectionsLocal/redundantCompanionReference/javaFakeGetter.1.java b/idea/testData/inspectionsLocal/redundantCompanionReference/javaFakeGetter.1.java new file mode 100644 index 00000000000..094d262c1a3 --- /dev/null +++ b/idea/testData/inspectionsLocal/redundantCompanionReference/javaFakeGetter.1.java @@ -0,0 +1,5 @@ +public class Bar { + public String getBar(Integer i) { + return ""; + } +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/redundantCompanionReference/javaFakeGetter.1.java.after b/idea/testData/inspectionsLocal/redundantCompanionReference/javaFakeGetter.1.java.after new file mode 100644 index 00000000000..094d262c1a3 --- /dev/null +++ b/idea/testData/inspectionsLocal/redundantCompanionReference/javaFakeGetter.1.java.after @@ -0,0 +1,5 @@ +public class Bar { + public String getBar(Integer i) { + return ""; + } +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/redundantCompanionReference/javaFakeGetter.kt b/idea/testData/inspectionsLocal/redundantCompanionReference/javaFakeGetter.kt new file mode 100644 index 00000000000..73fe9a0c047 --- /dev/null +++ b/idea/testData/inspectionsLocal/redundantCompanionReference/javaFakeGetter.kt @@ -0,0 +1,9 @@ +class Foo : Bar() { + fun test(): String { + return Companion.bar + } + + companion object { + val bar: String = "bar" + } +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/redundantCompanionReference/javaFakeGetter.kt.after b/idea/testData/inspectionsLocal/redundantCompanionReference/javaFakeGetter.kt.after new file mode 100644 index 00000000000..e4c512c2c66 --- /dev/null +++ b/idea/testData/inspectionsLocal/redundantCompanionReference/javaFakeGetter.kt.after @@ -0,0 +1,9 @@ +class Foo : Bar() { + fun test(): String { + return bar + } + + companion object { + val bar: String = "bar" + } +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/redundantCompanionReference/javaFakeSetter.1.java b/idea/testData/inspectionsLocal/redundantCompanionReference/javaFakeSetter.1.java new file mode 100644 index 00000000000..5439cfeaa1b --- /dev/null +++ b/idea/testData/inspectionsLocal/redundantCompanionReference/javaFakeSetter.1.java @@ -0,0 +1,5 @@ +public class Bar { + public String setBar(String bar) { + return "" + } +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/redundantCompanionReference/javaFakeSetter.1.java.after b/idea/testData/inspectionsLocal/redundantCompanionReference/javaFakeSetter.1.java.after new file mode 100644 index 00000000000..5439cfeaa1b --- /dev/null +++ b/idea/testData/inspectionsLocal/redundantCompanionReference/javaFakeSetter.1.java.after @@ -0,0 +1,5 @@ +public class Bar { + public String setBar(String bar) { + return "" + } +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/redundantCompanionReference/javaFakeSetter.kt b/idea/testData/inspectionsLocal/redundantCompanionReference/javaFakeSetter.kt new file mode 100644 index 00000000000..4cd1e41415b --- /dev/null +++ b/idea/testData/inspectionsLocal/redundantCompanionReference/javaFakeSetter.kt @@ -0,0 +1,9 @@ +class Foo : Bar() { + fun test() { + Companion.bar = "baz" + } + + companion object { + var bar: String = "bar" + } +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/redundantCompanionReference/javaFakeSetter.kt.after b/idea/testData/inspectionsLocal/redundantCompanionReference/javaFakeSetter.kt.after new file mode 100644 index 00000000000..7b94861af07 --- /dev/null +++ b/idea/testData/inspectionsLocal/redundantCompanionReference/javaFakeSetter.kt.after @@ -0,0 +1,9 @@ +class Foo : Bar() { + fun test() { + bar = "baz" + } + + companion object { + var bar: String = "bar" + } +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/redundantCompanionReference/javaGetter.1.java b/idea/testData/inspectionsLocal/redundantCompanionReference/javaGetter.1.java new file mode 100644 index 00000000000..625a083e396 --- /dev/null +++ b/idea/testData/inspectionsLocal/redundantCompanionReference/javaGetter.1.java @@ -0,0 +1,5 @@ +public class Bar { + public String getBar() { + return ""; + } +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/redundantCompanionReference/javaGetter.kt b/idea/testData/inspectionsLocal/redundantCompanionReference/javaGetter.kt new file mode 100644 index 00000000000..7410af49240 --- /dev/null +++ b/idea/testData/inspectionsLocal/redundantCompanionReference/javaGetter.kt @@ -0,0 +1,11 @@ +// PROBLEM: none + +class Foo : Bar() { + fun test(): String { + return Companion.bar + } + + companion object { + val bar: String = "bar" + } +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/redundantCompanionReference/javaSetter.1.java b/idea/testData/inspectionsLocal/redundantCompanionReference/javaSetter.1.java new file mode 100644 index 00000000000..4a245d31d57 --- /dev/null +++ b/idea/testData/inspectionsLocal/redundantCompanionReference/javaSetter.1.java @@ -0,0 +1,4 @@ +public class Bar { + public void setBar(String bar) { + } +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/redundantCompanionReference/javaSetter.kt b/idea/testData/inspectionsLocal/redundantCompanionReference/javaSetter.kt new file mode 100644 index 00000000000..5fa371b31d9 --- /dev/null +++ b/idea/testData/inspectionsLocal/redundantCompanionReference/javaSetter.kt @@ -0,0 +1,11 @@ +// PROBLEM: none + +class Foo : Bar() { + fun test() { + Companion.bar = "baz" + } + + companion object { + var bar: String = "bar" + } +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java index 69e76b88d10..788e3f8ecb2 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java @@ -6561,6 +6561,26 @@ public class LocalInspectionTestGenerated extends AbstractLocalInspectionTest { runTest("idea/testData/inspectionsLocal/redundantCompanionReference/inEnumEntry3.kt"); } + @TestMetadata("javaFakeGetter.kt") + public void testJavaFakeGetter() throws Exception { + runTest("idea/testData/inspectionsLocal/redundantCompanionReference/javaFakeGetter.kt"); + } + + @TestMetadata("javaFakeSetter.kt") + public void testJavaFakeSetter() throws Exception { + runTest("idea/testData/inspectionsLocal/redundantCompanionReference/javaFakeSetter.kt"); + } + + @TestMetadata("javaGetter.kt") + public void testJavaGetter() throws Exception { + runTest("idea/testData/inspectionsLocal/redundantCompanionReference/javaGetter.kt"); + } + + @TestMetadata("javaSetter.kt") + public void testJavaSetter() throws Exception { + runTest("idea/testData/inspectionsLocal/redundantCompanionReference/javaSetter.kt"); + } + @TestMetadata("methodArgument.kt") public void testMethodArgument() throws Exception { runTest("idea/testData/inspectionsLocal/redundantCompanionReference/methodArgument.kt");