Redundant companion reference: fix false positive with Java synthetic property
#KT-33771 Fixed
This commit is contained in:
committed by
Dmitry Gridin
parent
d72e55d1b7
commit
89180e2650
+19
-2
@@ -17,6 +17,8 @@ import org.jetbrains.kotlin.idea.references.mainReference
|
|||||||
import org.jetbrains.kotlin.idea.search.usagesSearch.descriptor
|
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.incremental.components.NoLookupLocation
|
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.name.Name
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.containingClass
|
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.descriptorUtil.getSuperInterfaces
|
||||||
import org.jetbrains.kotlin.resolve.scopes.utils.findFunction
|
import org.jetbrains.kotlin.resolve.scopes.utils.findFunction
|
||||||
import org.jetbrains.kotlin.resolve.scopes.utils.findVariable
|
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() {
|
class RedundantCompanionReferenceInspection : AbstractKotlinInspection() {
|
||||||
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor {
|
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor {
|
||||||
@@ -60,11 +64,24 @@ class RedundantCompanionReferenceInspection : AbstractKotlinInspection() {
|
|||||||
val containingClass = objectDeclaration.containingClass() ?: return false
|
val containingClass = objectDeclaration.containingClass() ?: return false
|
||||||
if (reference.containingClass() != containingClass && reference == parent.receiverExpression) return false
|
if (reference.containingClass() != containingClass && reference == parent.receiverExpression) return false
|
||||||
val containingClassDescriptor = containingClass.descriptor as? ClassDescriptor ?: return false
|
val containingClassDescriptor = containingClass.descriptor as? ClassDescriptor ?: return false
|
||||||
val selectorDescriptor = selectorExpression?.getResolvedCall(context)?.resultingDescriptor
|
when (val selectorDescriptor = selectorExpression?.getResolvedCall(context)?.resultingDescriptor) {
|
||||||
when (selectorDescriptor) {
|
|
||||||
is PropertyDescriptor -> {
|
is PropertyDescriptor -> {
|
||||||
val name = selectorDescriptor.name
|
val name = selectorDescriptor.name
|
||||||
if (containingClassDescriptor.findMemberVariable(name) != null) return false
|
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)
|
val variable = reference.getResolutionScope().findVariable(name, NoLookupLocation.FROM_IDE)
|
||||||
if (variable != null && variable.isLocalOrExtension(containingClassDescriptor)) return false
|
if (variable != null && variable.isLocalOrExtension(containingClassDescriptor)) return false
|
||||||
}
|
}
|
||||||
|
|||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
public class Bar {
|
||||||
|
public String getBar(Integer i) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
public class Bar {
|
||||||
|
public String getBar(Integer i) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
class Foo : Bar() {
|
||||||
|
fun test(): String {
|
||||||
|
return <caret>Companion.bar
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val bar: String = "bar"
|
||||||
|
}
|
||||||
|
}
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
class Foo : Bar() {
|
||||||
|
fun test(): String {
|
||||||
|
return bar
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val bar: String = "bar"
|
||||||
|
}
|
||||||
|
}
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
public class Bar {
|
||||||
|
public String setBar(String bar) {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
}
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
public class Bar {
|
||||||
|
public String setBar(String bar) {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
class Foo : Bar() {
|
||||||
|
fun test() {
|
||||||
|
<caret>Companion.bar = "baz"
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
var bar: String = "bar"
|
||||||
|
}
|
||||||
|
}
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
class Foo : Bar() {
|
||||||
|
fun test() {
|
||||||
|
bar = "baz"
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
var bar: String = "bar"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
public class Bar {
|
||||||
|
public String getBar() {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
// PROBLEM: none
|
||||||
|
|
||||||
|
class Foo : Bar() {
|
||||||
|
fun test(): String {
|
||||||
|
return <caret>Companion.bar
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val bar: String = "bar"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
public class Bar {
|
||||||
|
public void setBar(String bar) {
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
// PROBLEM: none
|
||||||
|
|
||||||
|
class Foo : Bar() {
|
||||||
|
fun test() {
|
||||||
|
<caret>Companion.bar = "baz"
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
var bar: String = "bar"
|
||||||
|
}
|
||||||
|
}
|
||||||
+20
@@ -6561,6 +6561,26 @@ public class LocalInspectionTestGenerated extends AbstractLocalInspectionTest {
|
|||||||
runTest("idea/testData/inspectionsLocal/redundantCompanionReference/inEnumEntry3.kt");
|
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")
|
@TestMetadata("methodArgument.kt")
|
||||||
public void testMethodArgument() throws Exception {
|
public void testMethodArgument() throws Exception {
|
||||||
runTest("idea/testData/inspectionsLocal/redundantCompanionReference/methodArgument.kt");
|
runTest("idea/testData/inspectionsLocal/redundantCompanionReference/methodArgument.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user