From 3983558ae7a9dbf51e098d121bc71407f654d6cc Mon Sep 17 00:00:00 2001 From: Toshiaki Kameyama Date: Tue, 15 Aug 2023 18:10:22 +0900 Subject: [PATCH] [kotlin] Fix false positive "Join declaration and assignment" with lateinit local var ^KTIJ-26650 Fixed closes https://github.com/JetBrains/intellij-community/pull/2543 GitOrigin-RevId: d3f1ab89d94461307ac20a01c3b6ed49d5045342 --- .../JoinDeclarationAndAssignmentIntention.kt | 33 ++++++++++++------- .../intentions/K1IntentionTestGenerated.java | 5 +++ .../usedBeforeAssignment.kt | 15 +++++++++ 3 files changed, 42 insertions(+), 11 deletions(-) create mode 100644 plugins/kotlin/idea/tests/testData/intentions/joinDeclarationAndAssignment/usedBeforeAssignment.kt diff --git a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/intentions/JoinDeclarationAndAssignmentIntention.kt b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/intentions/JoinDeclarationAndAssignmentIntention.kt index b0bef46bab3c..f31307dc7da3 100644 --- a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/intentions/JoinDeclarationAndAssignmentIntention.kt +++ b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/intentions/JoinDeclarationAndAssignmentIntention.kt @@ -10,17 +10,18 @@ import com.intellij.psi.PsiReferenceService import com.intellij.psi.PsiWhiteSpace import com.intellij.psi.util.PsiTreeUtil import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor +import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor -import org.jetbrains.kotlin.idea.base.resources.KotlinBundle import org.jetbrains.kotlin.idea.base.psi.replaced -import org.jetbrains.kotlin.util.match +import org.jetbrains.kotlin.idea.base.resources.KotlinBundle import org.jetbrains.kotlin.idea.caches.resolve.analyze +import org.jetbrains.kotlin.idea.codeinsight.api.classic.inspections.IntentionBasedInspection import org.jetbrains.kotlin.idea.codeinsight.api.classic.intentions.SelfTargetingRangeIntention import org.jetbrains.kotlin.idea.core.canOmitDeclaredType import org.jetbrains.kotlin.idea.core.moveCaret import org.jetbrains.kotlin.idea.core.unblockDocument -import org.jetbrains.kotlin.idea.codeinsight.api.classic.inspections.IntentionBasedInspection import org.jetbrains.kotlin.lexer.KtTokens +import org.jetbrains.kotlin.lexer.KtTokens.LATEINIT_KEYWORD import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.* import org.jetbrains.kotlin.resolve.BindingContext @@ -28,7 +29,7 @@ import org.jetbrains.kotlin.resolve.calls.util.getResolvedCall import org.jetbrains.kotlin.resolve.calls.util.getType import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.TypeUtils -import org.jetbrains.kotlin.psi.psiUtil.parents +import org.jetbrains.kotlin.util.match @Suppress("DEPRECATION") class JoinDeclarationAndAssignmentInspection : IntentionBasedInspection( @@ -61,13 +62,9 @@ class JoinDeclarationAndAssignmentIntention : SelfTargetingRangeIntention { - context[BindingContext.REFERENCE_TARGET, it] == propertyDescriptor - } - - if (isUsedInInitializer) return null + if (initializer.hasReference(propertyDescriptor, context)) return null if (hasLocalDependencies(initializer, element)) return null val isNonLocalVar = element.isVar && !element.isLocal @@ -79,6 +76,13 @@ class JoinDeclarationAndAssignmentIntention : SelfTargetingRangeIntention { + it.text == declarationName && context[BindingContext.REFERENCE_TARGET, it] == declaration + } + } } private fun KtElement.deleteWithPreviousWhitespace() { diff --git a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/intentions/K1IntentionTestGenerated.java b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/intentions/K1IntentionTestGenerated.java index 12f6b045460e..279a1e1c25fe 100644 --- a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/intentions/K1IntentionTestGenerated.java +++ b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/intentions/K1IntentionTestGenerated.java @@ -12526,6 +12526,11 @@ public abstract class K1IntentionTestGenerated extends AbstractK1IntentionTest { runTest("testData/intentions/joinDeclarationAndAssignment/singleConstructor.kt"); } + @TestMetadata("usedBeforeAssignment.kt") + public void testUsedBeforeAssignment() throws Exception { + runTest("testData/intentions/joinDeclarationAndAssignment/usedBeforeAssignment.kt"); + } + @TestMetadata("usedInAssignment.kt") public void testUsedInAssignment() throws Exception { runTest("testData/intentions/joinDeclarationAndAssignment/usedInAssignment.kt"); diff --git a/plugins/kotlin/idea/tests/testData/intentions/joinDeclarationAndAssignment/usedBeforeAssignment.kt b/plugins/kotlin/idea/tests/testData/intentions/joinDeclarationAndAssignment/usedBeforeAssignment.kt new file mode 100644 index 000000000000..94e97f67b0fa --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/intentions/joinDeclarationAndAssignment/usedBeforeAssignment.kt @@ -0,0 +1,15 @@ +// IS_APPLICABLE: false +fun test() { + lateinit var info: String + addActionListener { + println(info) + } + info = "" +} + +fun addActionListener(callback: () -> Unit) { +} + +fun println(a: Any) { +} +