From 80caa063b3ee09b4f6a2b8e2a2e7a9b8e69c2389 Mon Sep 17 00:00:00 2001 From: Dmitry Gridin Date: Thu, 12 Mar 2020 15:32:24 +0700 Subject: [PATCH] UnusedUnaryOperatorInspection: shouldn't report on annotation entry #KT-37294 Fixed --- .../UnusedUnaryOperatorInspection.kt | 8 ++++++++ .../unusedUnaryOperator/annotation.kt | 6 ++++++ .../unusedUnaryOperator/annotation2.kt | 7 +++++++ .../unusedUnaryOperator/annotation3.kt | 6 ++++++ .../unusedUnaryOperator/namedParameter.kt | 6 ++++++ .../LocalInspectionTestGenerated.java | 20 +++++++++++++++++++ 6 files changed, 53 insertions(+) create mode 100644 idea/testData/inspectionsLocal/unusedUnaryOperator/annotation.kt create mode 100644 idea/testData/inspectionsLocal/unusedUnaryOperator/annotation2.kt create mode 100644 idea/testData/inspectionsLocal/unusedUnaryOperator/annotation3.kt create mode 100644 idea/testData/inspectionsLocal/unusedUnaryOperator/namedParameter.kt diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/UnusedUnaryOperatorInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/UnusedUnaryOperatorInspection.kt index 6a96488478f..27f4ff3cf49 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/UnusedUnaryOperatorInspection.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/UnusedUnaryOperatorInspection.kt @@ -15,8 +15,11 @@ import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.util.textRangeIn import org.jetbrains.kotlin.lexer.KtTokens +import org.jetbrains.kotlin.psi.KtAnnotationEntry +import org.jetbrains.kotlin.psi.KtExpression import org.jetbrains.kotlin.psi.KtPrefixExpression import org.jetbrains.kotlin.psi.prefixExpressionVisitor +import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsExpression import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode @@ -27,6 +30,8 @@ class UnusedUnaryOperatorInspection : AbstractKotlinInspection() { val operationToken = prefix.operationToken if (operationToken != KtTokens.PLUS && operationToken != KtTokens.MINUS) return + // ISSUE: KT-37447 + if (prefix.isInAnnotationEntry) return val context = prefix.analyze(BodyResolveMode.PARTIAL_WITH_CFA) if (prefix.isUsedAsExpression(context)) return val operatorDescriptor = prefix.operationReference.getResolvedCall(context)?.resultingDescriptor as? DeclarationDescriptor ?: return @@ -53,3 +58,6 @@ class UnusedUnaryOperatorInspection : AbstractKotlinInspection() { } } } + +private val KtPrefixExpression.isInAnnotationEntry: Boolean + get() = parentsWithSelf.takeWhile { it is KtExpression }.last().parent?.parent?.parent is KtAnnotationEntry \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/unusedUnaryOperator/annotation.kt b/idea/testData/inspectionsLocal/unusedUnaryOperator/annotation.kt new file mode 100644 index 00000000000..32eb0e6417b --- /dev/null +++ b/idea/testData/inspectionsLocal/unusedUnaryOperator/annotation.kt @@ -0,0 +1,6 @@ +// PROBLEM: none + +@Target(AnnotationTarget.VALUE_PARAMETER) +annotation class Range(val min: Long = 0) + +fun foo(@Range(min = -90L) x: Int) {} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/unusedUnaryOperator/annotation2.kt b/idea/testData/inspectionsLocal/unusedUnaryOperator/annotation2.kt new file mode 100644 index 00000000000..2f96687a897 --- /dev/null +++ b/idea/testData/inspectionsLocal/unusedUnaryOperator/annotation2.kt @@ -0,0 +1,7 @@ +// PROBLEM: none + +@Target(AnnotationTarget.FUNCTION) +annotation class Range(val min: Long = 0) + +@Range(min = -90L) +fun foo(x: Int) {} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/unusedUnaryOperator/annotation3.kt b/idea/testData/inspectionsLocal/unusedUnaryOperator/annotation3.kt new file mode 100644 index 00000000000..9b4e8f83bce --- /dev/null +++ b/idea/testData/inspectionsLocal/unusedUnaryOperator/annotation3.kt @@ -0,0 +1,6 @@ +// PROBLEM: none + +@Target(AnnotationTarget.VALUE_PARAMETER) +annotation class Range(val min: Long = 0) + +fun foo(@Range(min = -(-90L)) x: Int) {} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/unusedUnaryOperator/namedParameter.kt b/idea/testData/inspectionsLocal/unusedUnaryOperator/namedParameter.kt new file mode 100644 index 00000000000..5e09ef5db1a --- /dev/null +++ b/idea/testData/inspectionsLocal/unusedUnaryOperator/namedParameter.kt @@ -0,0 +1,6 @@ +// PROBLEM: none + +fun a(a: Int) = Unit +fun b() { + a(a = -1) +} \ 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 cb5ea900ff9..ce4f6ac49e0 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java @@ -13308,6 +13308,21 @@ public class LocalInspectionTestGenerated extends AbstractLocalInspectionTest { KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/testData/inspectionsLocal/unusedUnaryOperator"), Pattern.compile("^([\\w\\-_]+)\\.(kt|kts)$"), null, true); } + @TestMetadata("annotation.kt") + public void testAnnotation() throws Exception { + runTest("idea/testData/inspectionsLocal/unusedUnaryOperator/annotation.kt"); + } + + @TestMetadata("annotation2.kt") + public void testAnnotation2() throws Exception { + runTest("idea/testData/inspectionsLocal/unusedUnaryOperator/annotation2.kt"); + } + + @TestMetadata("annotation3.kt") + public void testAnnotation3() throws Exception { + runTest("idea/testData/inspectionsLocal/unusedUnaryOperator/annotation3.kt"); + } + @TestMetadata("basic.kt") public void testBasic() throws Exception { runTest("idea/testData/inspectionsLocal/unusedUnaryOperator/basic.kt"); @@ -13318,6 +13333,11 @@ public class LocalInspectionTestGenerated extends AbstractLocalInspectionTest { runTest("idea/testData/inspectionsLocal/unusedUnaryOperator/basic2.kt"); } + @TestMetadata("namedParameter.kt") + public void testNamedParameter() throws Exception { + runTest("idea/testData/inspectionsLocal/unusedUnaryOperator/namedParameter.kt"); + } + @TestMetadata("usedAsExpression.kt") public void testUsedAsExpression() throws Exception { runTest("idea/testData/inspectionsLocal/unusedUnaryOperator/usedAsExpression.kt");