Join declaration & assignment is no more suggested in case of potential smart cast available #KT-15412 Fixed
This commit is contained in:
+20
-3
@@ -21,6 +21,7 @@ import com.intellij.openapi.editor.ScrollType
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiReferenceService
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.idea.core.canOmitDeclaredType
|
||||
import org.jetbrains.kotlin.idea.core.moveCaret
|
||||
import org.jetbrains.kotlin.idea.core.unblockDocument
|
||||
@@ -28,6 +29,10 @@ import org.jetbrains.kotlin.idea.inspections.IntentionBasedInspection
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getType
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
|
||||
class JoinDeclarationAndAssignmentInspection : IntentionBasedInspection<KtProperty>(
|
||||
JoinDeclarationAndAssignmentIntention::class,
|
||||
@@ -39,6 +44,12 @@ class JoinDeclarationAndAssignmentIntention : SelfTargetingOffsetIndependentInte
|
||||
"Join declaration and assignment"
|
||||
) {
|
||||
|
||||
private fun equalNullableTypes(type1: KotlinType?, type2: KotlinType?): Boolean {
|
||||
if (type1 == null) return type2 == null
|
||||
if (type2 == null) return false
|
||||
return TypeUtils.equalTypes(type1, type2)
|
||||
}
|
||||
|
||||
override fun isApplicableTo(element: KtProperty): Boolean {
|
||||
if (element.hasDelegate()
|
||||
|| element.hasInitializer()
|
||||
@@ -50,7 +61,13 @@ class JoinDeclarationAndAssignmentIntention : SelfTargetingOffsetIndependentInte
|
||||
}
|
||||
|
||||
val assignment = findAssignment(element) ?: return false
|
||||
return assignment.right?.let { hasNoLocalDependencies(it, element.parent) } ?: false
|
||||
return assignment.right?.let {
|
||||
hasNoLocalDependencies(it, element.parent) &&
|
||||
assignment.analyze().let { context ->
|
||||
(element.isVar && !element.isLocal) ||
|
||||
equalNullableTypes(it.getType(context), context[BindingContext.TYPE, element.typeReference])
|
||||
}
|
||||
} ?: false
|
||||
}
|
||||
|
||||
override fun applyTo(element: KtProperty, editor: Editor?) {
|
||||
@@ -60,7 +77,7 @@ class JoinDeclarationAndAssignmentIntention : SelfTargetingOffsetIndependentInte
|
||||
val initializer = assignment.right ?: return
|
||||
val newInitializer = element.setInitializer(initializer)!!
|
||||
|
||||
val initializerBlock = assignment.parent?.parent as? KtAnonymousInitializer
|
||||
val initializerBlock = assignment.parent.parent as? KtAnonymousInitializer
|
||||
assignment.delete()
|
||||
if (initializerBlock != null && (initializerBlock.body as? KtBlockExpression)?.isEmpty() == true) {
|
||||
initializerBlock.delete()
|
||||
@@ -108,7 +125,7 @@ class JoinDeclarationAndAssignmentIntention : SelfTargetingOffsetIndependentInte
|
||||
if (assignments.any { it.parent.invalidParent() }) return null
|
||||
|
||||
val first = assignments.firstOrNull() ?: return null
|
||||
if (assignments.any { it !== first && it.parent?.parent is KtSecondaryConstructor}) return null
|
||||
if (assignments.any { it !== first && it.parent.parent is KtSecondaryConstructor}) return null
|
||||
return first
|
||||
}
|
||||
|
||||
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
// IS_APPLICABLE: true
|
||||
// WITH_RUNTIME
|
||||
fun foo() {
|
||||
val x: String<caret>
|
||||
x = System.getProperty("")
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
// IS_APPLICABLE: true
|
||||
// WITH_RUNTIME
|
||||
fun foo() {
|
||||
val x: String = System.getProperty("")
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
// IS_APPLICABLE: false
|
||||
fun foo() {
|
||||
val x: Any<caret>
|
||||
x = "123"
|
||||
x.length // Smart cast before join, error after join
|
||||
}
|
||||
@@ -8754,6 +8754,18 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/intentions/joinDeclarationAndAssignment"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("assignmentForFlexible.kt")
|
||||
public void testAssignmentForFlexible() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/joinDeclarationAndAssignment/assignmentForFlexible.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("assignmentForSmartCast.kt")
|
||||
public void testAssignmentForSmartCast() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/joinDeclarationAndAssignment/assignmentForSmartCast.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("assignmentInIf.kt")
|
||||
public void testAssignmentInIf() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/joinDeclarationAndAssignment/assignmentInIf.kt");
|
||||
|
||||
Reference in New Issue
Block a user