From a3252b9480b16200632a2170b0ef284a389739e1 Mon Sep 17 00:00:00 2001 From: Toshiaki Kameyama Date: Mon, 10 Feb 2020 13:38:16 +0900 Subject: [PATCH] Unused symbol: fix false positive in anonymous object in top level or companion object #KT-31800 Fixed #KT-20868 Fixed --- .../kotlin/psi/KtNamedDeclarationStub.java | 15 +++++++++++++++ .../objectExpressionMemberInCompanion.0.kt | 14 ++++++++++++++ ...objectExpressionMemberInCompanion.results.txt | 1 + .../objectExpressionMemberInTopLevel.0.kt | 12 ++++++++++++ .../objectExpressionMemberInTopLevel.results.txt | 1 + .../unusedSymbol/inAnonymousDeeplyInTopLevel.kt | 16 ++++++++++++++++ .../unusedSymbol/inAnonymousInCompanion.kt | 13 +++++++++++++ .../unusedSymbol/inAnonymousInTopLovel.kt | 9 +++++++++ .../findUsages/FindUsagesTestGenerated.java | 10 ++++++++++ .../LocalInspectionTestGenerated.java | 15 +++++++++++++++ 10 files changed, 106 insertions(+) create mode 100644 idea/testData/findUsages/kotlin/findFunctionUsages/objectExpressionMemberInCompanion.0.kt create mode 100644 idea/testData/findUsages/kotlin/findFunctionUsages/objectExpressionMemberInCompanion.results.txt create mode 100644 idea/testData/findUsages/kotlin/findFunctionUsages/objectExpressionMemberInTopLevel.0.kt create mode 100644 idea/testData/findUsages/kotlin/findFunctionUsages/objectExpressionMemberInTopLevel.results.txt create mode 100644 idea/testData/inspectionsLocal/unusedSymbol/inAnonymousDeeplyInTopLevel.kt create mode 100644 idea/testData/inspectionsLocal/unusedSymbol/inAnonymousInCompanion.kt create mode 100644 idea/testData/inspectionsLocal/unusedSymbol/inAnonymousInTopLovel.kt diff --git a/compiler/psi/src/org/jetbrains/kotlin/psi/KtNamedDeclarationStub.java b/compiler/psi/src/org/jetbrains/kotlin/psi/KtNamedDeclarationStub.java index bd8f902252a..42a7466506a 100644 --- a/compiler/psi/src/org/jetbrains/kotlin/psi/KtNamedDeclarationStub.java +++ b/compiler/psi/src/org/jetbrains/kotlin/psi/KtNamedDeclarationStub.java @@ -130,6 +130,21 @@ abstract class KtNamedDeclarationStub> extends KtElement enclosingBlock = KtPsiUtil.getEnclosingElementForLocalDeclaration(this, false); if (enclosingBlock != null) { PsiElement enclosingParent = enclosingBlock.getParent(); + + KtObjectDeclaration containingObject = PsiTreeUtil.getParentOfType(this, KtObjectDeclaration.class); + if (containingObject != null && containingObject.isObjectLiteral()) { + KtDeclarationWithInitializer declaration = + PsiTreeUtil.getParentOfType(containingObject, KtDeclarationWithInitializer.class); + if (declaration != null && declaration.hasModifier(KtTokens.PRIVATE_KEYWORD)) { + if (enclosingParent instanceof KtFile) { + return new LocalSearchScope(enclosingParent); + } + if (enclosingParent instanceof KtObjectDeclaration && ((KtObjectDeclaration) enclosingParent).isCompanion()) { + return new LocalSearchScope(enclosingParent.getParent()); + } + } + } + if (enclosingParent instanceof KtContainerNode) { enclosingParent = enclosingParent.getParent(); } diff --git a/idea/testData/findUsages/kotlin/findFunctionUsages/objectExpressionMemberInCompanion.0.kt b/idea/testData/findUsages/kotlin/findFunctionUsages/objectExpressionMemberInCompanion.0.kt new file mode 100644 index 00000000000..45741d7a903 --- /dev/null +++ b/idea/testData/findUsages/kotlin/findFunctionUsages/objectExpressionMemberInCompanion.0.kt @@ -0,0 +1,14 @@ +// PSI_ELEMENT: org.jetbrains.kotlin.psi.KtNamedFunction +// OPTIONS: usages +class Foo { + companion object { + private val localObject = object : Any() { + fun f() { + } + } + } + + fun bar() { + localObject.f() + } +} \ No newline at end of file diff --git a/idea/testData/findUsages/kotlin/findFunctionUsages/objectExpressionMemberInCompanion.results.txt b/idea/testData/findUsages/kotlin/findFunctionUsages/objectExpressionMemberInCompanion.results.txt new file mode 100644 index 00000000000..b078e345293 --- /dev/null +++ b/idea/testData/findUsages/kotlin/findFunctionUsages/objectExpressionMemberInCompanion.results.txt @@ -0,0 +1 @@ +Function call 12 localObject.f() diff --git a/idea/testData/findUsages/kotlin/findFunctionUsages/objectExpressionMemberInTopLevel.0.kt b/idea/testData/findUsages/kotlin/findFunctionUsages/objectExpressionMemberInTopLevel.0.kt new file mode 100644 index 00000000000..b9e831784b4 --- /dev/null +++ b/idea/testData/findUsages/kotlin/findFunctionUsages/objectExpressionMemberInTopLevel.0.kt @@ -0,0 +1,12 @@ +// PSI_ELEMENT: org.jetbrains.kotlin.psi.KtNamedFunction +// OPTIONS: usages +private val localObject = object : Any() { + fun f() { + } +} + +class Foo { + fun bar() { + localObject.f() + } +} \ No newline at end of file diff --git a/idea/testData/findUsages/kotlin/findFunctionUsages/objectExpressionMemberInTopLevel.results.txt b/idea/testData/findUsages/kotlin/findFunctionUsages/objectExpressionMemberInTopLevel.results.txt new file mode 100644 index 00000000000..9ebf98c0309 --- /dev/null +++ b/idea/testData/findUsages/kotlin/findFunctionUsages/objectExpressionMemberInTopLevel.results.txt @@ -0,0 +1 @@ +Function call 10 localObject.f() diff --git a/idea/testData/inspectionsLocal/unusedSymbol/inAnonymousDeeplyInTopLevel.kt b/idea/testData/inspectionsLocal/unusedSymbol/inAnonymousDeeplyInTopLevel.kt new file mode 100644 index 00000000000..6bec79aa8b6 --- /dev/null +++ b/idea/testData/inspectionsLocal/unusedSymbol/inAnonymousDeeplyInTopLevel.kt @@ -0,0 +1,16 @@ +// PROBLEM: none +// WITH_RUNTIME + +private val xs = listOf(1, 2, 3).flatMap { x -> + listOf(3, 4, 5).map { y -> + object { + val value = x + y + } + } +} + +fun foo() { + xs.forEach { + println("value: " + it.value) + } +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/unusedSymbol/inAnonymousInCompanion.kt b/idea/testData/inspectionsLocal/unusedSymbol/inAnonymousInCompanion.kt new file mode 100644 index 00000000000..2aa33456097 --- /dev/null +++ b/idea/testData/inspectionsLocal/unusedSymbol/inAnonymousInCompanion.kt @@ -0,0 +1,13 @@ +// PROBLEM: none +class Some { + fun bar() { + writer().sayHello() + } + + companion object { + private fun writer() = object { + fun sayHello() { + } + } + } +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/unusedSymbol/inAnonymousInTopLovel.kt b/idea/testData/inspectionsLocal/unusedSymbol/inAnonymousInTopLovel.kt new file mode 100644 index 00000000000..1620dd5f605 --- /dev/null +++ b/idea/testData/inspectionsLocal/unusedSymbol/inAnonymousInTopLovel.kt @@ -0,0 +1,9 @@ +// PROBLEM: none +fun main() { + writer.sayHello() +} + +private val writer = object { + fun sayHello() { + } +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/findUsages/FindUsagesTestGenerated.java b/idea/tests/org/jetbrains/kotlin/findUsages/FindUsagesTestGenerated.java index 16da2f22798..5067a677bd7 100644 --- a/idea/tests/org/jetbrains/kotlin/findUsages/FindUsagesTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/findUsages/FindUsagesTestGenerated.java @@ -719,6 +719,16 @@ public class FindUsagesTestGenerated extends AbstractFindUsagesTest { runTest("idea/testData/findUsages/kotlin/findFunctionUsages/objectExpressionMemberInClass.0.kt"); } + @TestMetadata("objectExpressionMemberInCompanion.0.kt") + public void testObjectExpressionMemberInCompanion() throws Exception { + runTest("idea/testData/findUsages/kotlin/findFunctionUsages/objectExpressionMemberInCompanion.0.kt"); + } + + @TestMetadata("objectExpressionMemberInTopLevel.0.kt") + public void testObjectExpressionMemberInTopLevel() throws Exception { + runTest("idea/testData/findUsages/kotlin/findFunctionUsages/objectExpressionMemberInTopLevel.0.kt"); + } + @TestMetadata("synthesizedFunction.0.kt") public void testSynthesizedFunction() throws Exception { runTest("idea/testData/findUsages/kotlin/findFunctionUsages/synthesizedFunction.0.kt"); diff --git a/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java index 51084291353..7b6666f06c3 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java @@ -13019,6 +13019,21 @@ public class LocalInspectionTestGenerated extends AbstractLocalInspectionTest { runTest("idea/testData/inspectionsLocal/unusedSymbol/inAnonymousDeeply.kt"); } + @TestMetadata("inAnonymousDeeplyInTopLevel.kt") + public void testInAnonymousDeeplyInTopLevel() throws Exception { + runTest("idea/testData/inspectionsLocal/unusedSymbol/inAnonymousDeeplyInTopLevel.kt"); + } + + @TestMetadata("inAnonymousInCompanion.kt") + public void testInAnonymousInCompanion() throws Exception { + runTest("idea/testData/inspectionsLocal/unusedSymbol/inAnonymousInCompanion.kt"); + } + + @TestMetadata("inAnonymousInTopLovel.kt") + public void testInAnonymousInTopLovel() throws Exception { + runTest("idea/testData/inspectionsLocal/unusedSymbol/inAnonymousInTopLovel.kt"); + } + @TestMetadata("inAnonymousRunWrapped.kt") public void testInAnonymousRunWrapped() throws Exception { runTest("idea/testData/inspectionsLocal/unusedSymbol/inAnonymousRunWrapped.kt");