From 89b1307e16b7165b6c00760c0539565fca534b5c Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Fri, 13 May 2022 11:39:13 +0300 Subject: [PATCH] [FE 1.0] Don't report UNUSED_* warnings on local properties with delegate ^KT-25527 Fixed --- ...CompilerTestFE10TestdataTestGenerated.java | 6 +++ ...irOldFrontendDiagnosticsTestGenerated.java | 6 +++ ...DiagnosticsWithLightTreeTestGenerated.java | 6 +++ .../cfg/ControlFlowInformationProviderImpl.kt | 11 ++++- .../unusedPropertyWithCustomAccessors.fir.kt | 40 +++++++++++++++++++ .../unusedPropertyWithCustomAccessors.kt | 40 +++++++++++++++++++ .../unusedPropertyWithCustomAccessors.txt | 14 +++++++ .../test/runners/DiagnosticTestGenerated.java | 6 +++ 8 files changed, 127 insertions(+), 2 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/controlFlowAnalysis/unusedPropertyWithCustomAccessors.fir.kt create mode 100644 compiler/testData/diagnostics/tests/controlFlowAnalysis/unusedPropertyWithCustomAccessors.kt create mode 100644 compiler/testData/diagnostics/tests/controlFlowAnalysis/unusedPropertyWithCustomAccessors.txt diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java index 12db2a6840d..a2e91491649 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java @@ -5944,6 +5944,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/unresolvedReference.kt"); } + @Test + @TestMetadata("unusedPropertyWithCustomAccessors.kt") + public void testUnusedPropertyWithCustomAccessors() throws Exception { + runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/unusedPropertyWithCustomAccessors.kt"); + } + @Test @TestMetadata("useUninitializedInLambda.kt") public void testUseUninitializedInLambda() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java index f0282405cb7..0dd480dab2b 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java @@ -5944,6 +5944,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/unresolvedReference.kt"); } + @Test + @TestMetadata("unusedPropertyWithCustomAccessors.kt") + public void testUnusedPropertyWithCustomAccessors() throws Exception { + runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/unusedPropertyWithCustomAccessors.kt"); + } + @Test @TestMetadata("useUninitializedInLambda.kt") public void testUseUninitializedInLambda() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java index 67f4bfa4671..68680b7ed58 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java @@ -5944,6 +5944,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/unresolvedReference.kt"); } + @Test + @TestMetadata("unusedPropertyWithCustomAccessors.kt") + public void testUnusedPropertyWithCustomAccessors() throws Exception { + runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/unusedPropertyWithCustomAccessors.kt"); + } + @Test @TestMetadata("useUninitializedInLambda.kt") public void testUseUninitializedInLambda() throws Exception { diff --git a/compiler/frontend/cfg/src/org/jetbrains/kotlin/cfg/ControlFlowInformationProviderImpl.kt b/compiler/frontend/cfg/src/org/jetbrains/kotlin/cfg/ControlFlowInformationProviderImpl.kt index 180cb8f1791..51afd2071a0 100644 --- a/compiler/frontend/cfg/src/org/jetbrains/kotlin/cfg/ControlFlowInformationProviderImpl.kt +++ b/compiler/frontend/cfg/src/org/jetbrains/kotlin/cfg/ControlFlowInformationProviderImpl.kt @@ -676,7 +676,9 @@ class ControlFlowInformationProviderImpl private constructor( when (expressionInQuestion) { is KtBinaryExpression -> if (expressionInQuestion.operationToken === KtTokens.EQ) { expressionInQuestion.right?.let { - report(Errors.UNUSED_VALUE.on(expressionInQuestion, it, variableDescriptor), ctxt) + if (!variableDescriptor.isLocalVariableWithDelegate) { + report(Errors.UNUSED_VALUE.on(expressionInQuestion, it, variableDescriptor), ctxt) + } } } is KtPostfixExpression -> { @@ -689,6 +691,9 @@ class ControlFlowInformationProviderImpl private constructor( } } + private val VariableDescriptor.isLocalVariableWithDelegate: Boolean + get() = this is LocalVariableDescriptor && this.isDelegated + private fun processUnusedDeclaration( element: KtNamedDeclaration, variableDescriptor: VariableDescriptor, @@ -710,7 +715,9 @@ class ControlFlowInformationProviderImpl private constructor( processUnusedParameter(ctxt, element, variableDescriptor) } } else if (variableUseState === ONLY_WRITTEN_NEVER_READ && KtPsiUtil.isRemovableVariableDeclaration(element)) { - report(Errors.ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE.on(element, variableDescriptor), ctxt) + if (!variableDescriptor.isLocalVariableWithDelegate) { + report(Errors.ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE.on(element, variableDescriptor), ctxt) + } } else if (variableUseState === WRITTEN_AFTER_READ && element is KtVariableDeclaration) { when (element) { is KtProperty -> diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/unusedPropertyWithCustomAccessors.fir.kt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/unusedPropertyWithCustomAccessors.fir.kt new file mode 100644 index 00000000000..37301863e49 --- /dev/null +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/unusedPropertyWithCustomAccessors.fir.kt @@ -0,0 +1,40 @@ +// ISSUE: KT-25527 + +import kotlin.reflect.KProperty + +fun test_1(delegate: Delegate) { + var p1 by delegate + p1 = 10 + + var p2 by delegate + p2++ + + var p3 by delegate + ++p3 +} + +fun test_2() { + var p1 = 0 + p1 = 10 + + var p2: Int + p2 = 10 + + var p3 = 1 + p3++ + + var p4 = 1 + ++p4 +} + +class Delegate { + var prop: Int = 0 + + operator fun getValue(thisRef: Any?, property: KProperty<*>): Int { + return prop + } + + operator fun setValue(thisRef: Any?, property: KProperty<*>, value: Int) { + prop = value + } +} diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/unusedPropertyWithCustomAccessors.kt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/unusedPropertyWithCustomAccessors.kt new file mode 100644 index 00000000000..40c097a3e4b --- /dev/null +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/unusedPropertyWithCustomAccessors.kt @@ -0,0 +1,40 @@ +// ISSUE: KT-25527 + +import kotlin.reflect.KProperty + +fun test_1(delegate: Delegate) { + var p1 by delegate + p1 = 10 + + var p2 by delegate + p2++ + + var p3 by delegate + ++p3 +} + +fun test_2() { + var p1 = 0 + p1 = 10 + + var p2: Int + p2 = 10 + + var p3 = 1 + p3++ + + var p4 = 1 + ++p4 +} + +class Delegate { + var prop: Int = 0 + + operator fun getValue(thisRef: Any?, property: KProperty<*>): Int { + return prop + } + + operator fun setValue(thisRef: Any?, property: KProperty<*>, value: Int) { + prop = value + } +} diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/unusedPropertyWithCustomAccessors.txt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/unusedPropertyWithCustomAccessors.txt new file mode 100644 index 00000000000..6d9708f3a4a --- /dev/null +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/unusedPropertyWithCustomAccessors.txt @@ -0,0 +1,14 @@ +package + +public fun test_1(/*0*/ delegate: Delegate): kotlin.Unit +public fun test_2(): kotlin.Unit + +public final class Delegate { + public constructor Delegate() + public final var prop: kotlin.Int + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public final operator fun getValue(/*0*/ thisRef: kotlin.Any?, /*1*/ property: kotlin.reflect.KProperty<*>): kotlin.Int + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public final operator fun setValue(/*0*/ thisRef: kotlin.Any?, /*1*/ property: kotlin.reflect.KProperty<*>, /*2*/ value: kotlin.Int): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java index 8a3b50763fb..adf624f01ff 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java @@ -5950,6 +5950,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/unresolvedReference.kt"); } + @Test + @TestMetadata("unusedPropertyWithCustomAccessors.kt") + public void testUnusedPropertyWithCustomAccessors() throws Exception { + runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/unusedPropertyWithCustomAccessors.kt"); + } + @Test @TestMetadata("useUninitializedInLambda.kt") public void testUseUninitializedInLambda() throws Exception {