From ab973b2ff0a68b92dc04c9c0a8698a6d45738e48 Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Mon, 2 Apr 2018 21:23:05 +0300 Subject: [PATCH] Fix several false positives and make safer "redundant companion ref" Don't report it on an import directive #KT-23520 Fixed Don't report it if companion nested class is referenced #KT-23519 Fixed Check companion reference both by descriptor and by name --- .../RedundantCompanionReferenceInspection.kt | 22 ++++++++++------- .../companionDoubleNested.kt | 11 +++++++++ .../companionNested.kt | 9 +++++++ .../redundantCompanionReference/import.kt | 13 ++++++++++ .../redundantCompanionReference/named.kt | 9 +++++++ .../named.kt.after | 9 +++++++ .../LocalInspectionTestGenerated.java | 24 +++++++++++++++++++ 7 files changed, 88 insertions(+), 9 deletions(-) create mode 100644 idea/testData/inspectionsLocal/redundantCompanionReference/companionDoubleNested.kt create mode 100644 idea/testData/inspectionsLocal/redundantCompanionReference/companionNested.kt create mode 100644 idea/testData/inspectionsLocal/redundantCompanionReference/import.kt create mode 100644 idea/testData/inspectionsLocal/redundantCompanionReference/named.kt create mode 100644 idea/testData/inspectionsLocal/redundantCompanionReference/named.kt.after diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/RedundantCompanionReferenceInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/RedundantCompanionReferenceInspection.kt index 175728edbfc..79d368ae975 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/RedundantCompanionReferenceInspection.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/RedundantCompanionReferenceInspection.kt @@ -11,24 +11,28 @@ import com.intellij.codeInspection.ProblemHighlightType import com.intellij.codeInspection.ProblemsHolder import com.intellij.openapi.project.Project import com.intellij.psi.PsiElementVisitor +import org.jetbrains.kotlin.descriptors.ConstructorDescriptor +import org.jetbrains.kotlin.idea.caches.resolve.resolveToCall import org.jetbrains.kotlin.idea.references.mainReference -import org.jetbrains.kotlin.idea.search.usagesSearch.descriptor -import org.jetbrains.kotlin.psi.KtDotQualifiedExpression -import org.jetbrains.kotlin.psi.KtObjectDeclaration -import org.jetbrains.kotlin.psi.KtReferenceExpression -import org.jetbrains.kotlin.psi.referenceExpressionVisitor -import org.jetbrains.kotlin.resolve.DescriptorUtils +import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType class RedundantCompanionReferenceInspection : AbstractKotlinInspection() { override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor { return referenceExpressionVisitor(fun(expression) { val parent = expression.parent as? KtDotQualifiedExpression ?: return if (expression == parent.selectorExpression && parent.parent !is KtDotQualifiedExpression) return + if (parent.getStrictParentOfType() != null) return - val descriptor = (expression.mainReference.resolve() as? KtObjectDeclaration)?.descriptor ?: return - if (!DescriptorUtils.isCompanionObject(descriptor)) return + val objectDeclaration = expression.mainReference.resolve() as? KtObjectDeclaration ?: return + if (!objectDeclaration.isCompanion()) return + if (expression.text != objectDeclaration.name) return - if (expression == parent.receiverExpression && expression.text == descriptor.containingDeclaration?.name?.asString()) return + val grandParent = parent.parent as? KtQualifiedExpression + if (grandParent != null) { + val grandParentDescriptor = grandParent.resolveToCall()?.resultingDescriptor ?: return + if (grandParentDescriptor is ConstructorDescriptor) return + } holder.registerProblem( expression, diff --git a/idea/testData/inspectionsLocal/redundantCompanionReference/companionDoubleNested.kt b/idea/testData/inspectionsLocal/redundantCompanionReference/companionDoubleNested.kt new file mode 100644 index 00000000000..7a345e1b01a --- /dev/null +++ b/idea/testData/inspectionsLocal/redundantCompanionReference/companionDoubleNested.kt @@ -0,0 +1,11 @@ +// PROBLEM: none + +class Owner { + companion object { + class InCompanion { + class Nested + } + } +} + +val y = Owner.Companion.InCompanion.Nested() \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/redundantCompanionReference/companionNested.kt b/idea/testData/inspectionsLocal/redundantCompanionReference/companionNested.kt new file mode 100644 index 00000000000..0e89715c92c --- /dev/null +++ b/idea/testData/inspectionsLocal/redundantCompanionReference/companionNested.kt @@ -0,0 +1,9 @@ +// PROBLEM: none + +class Owner { + companion object { + class InCompanion + } +} + +val y = Owner.Companion.InCompanion() \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/redundantCompanionReference/import.kt b/idea/testData/inspectionsLocal/redundantCompanionReference/import.kt new file mode 100644 index 00000000000..d6ded128f31 --- /dev/null +++ b/idea/testData/inspectionsLocal/redundantCompanionReference/import.kt @@ -0,0 +1,13 @@ +// PROBLEM: none + +import Owner.Companion.some + +class Owner { + companion object { + const val some = "" + } +} + +class User { + val anything = some +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/redundantCompanionReference/named.kt b/idea/testData/inspectionsLocal/redundantCompanionReference/named.kt new file mode 100644 index 00000000000..595464515d9 --- /dev/null +++ b/idea/testData/inspectionsLocal/redundantCompanionReference/named.kt @@ -0,0 +1,9 @@ +class C { + companion object Obj { + fun create() = C() + } +} + +fun test() { + C.Obj.create() +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/redundantCompanionReference/named.kt.after b/idea/testData/inspectionsLocal/redundantCompanionReference/named.kt.after new file mode 100644 index 00000000000..a30b7603edd --- /dev/null +++ b/idea/testData/inspectionsLocal/redundantCompanionReference/named.kt.after @@ -0,0 +1,9 @@ +class C { + companion object Obj { + fun create() = C() + } +} + +fun test() { + C.create() +} \ 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 5edcf55f27e..6ca16ffac15 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java @@ -2553,6 +2553,18 @@ public class LocalInspectionTestGenerated extends AbstractLocalInspectionTest { doTest(fileName); } + @TestMetadata("companionDoubleNested.kt") + public void testCompanionDoubleNested() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/redundantCompanionReference/companionDoubleNested.kt"); + doTest(fileName); + } + + @TestMetadata("companionNested.kt") + public void testCompanionNested() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/redundantCompanionReference/companionNested.kt"); + doTest(fileName); + } + @TestMetadata("directCompanion.kt") public void testDirectCompanion() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/redundantCompanionReference/directCompanion.kt"); @@ -2565,12 +2577,24 @@ public class LocalInspectionTestGenerated extends AbstractLocalInspectionTest { doTest(fileName); } + @TestMetadata("import.kt") + public void testImport() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/redundantCompanionReference/import.kt"); + doTest(fileName); + } + @TestMetadata("methodArgument.kt") public void testMethodArgument() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/redundantCompanionReference/methodArgument.kt"); doTest(fileName); } + @TestMetadata("named.kt") + public void testNamed() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/redundantCompanionReference/named.kt"); + doTest(fileName); + } + @TestMetadata("notCompanion.kt") public void testNotCompanion() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/redundantCompanionReference/notCompanion.kt");