diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/loopToCallChain/utils.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/loopToCallChain/utils.kt index 17bf0847355..cf3cde3787c 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/loopToCallChain/utils.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/loopToCallChain/utils.kt @@ -240,12 +240,20 @@ data class VariableInitialization( val initializationStatement: KtExpression, val initializer: KtExpression) +//TODO: we need more correctness checks (if variable is non-local or is local but can be changed by some local functions) fun KtExpression.detectInitializationBeforeLoop(loop: KtForExpression): VariableInitialization? { if (this !is KtNameReferenceExpression) return null if (getQualifiedExpressionForSelector() != null) return null val variable = this.mainReference.resolve() as? KtProperty ?: return null - if (variable != loop.previousStatement()) return null //TODO: support initializer not right before the loop - //TODO: support assignment instead of initializer - val initializer = variable.initializer ?: return null - return VariableInitialization(variable, variable, initializer) + val statementBeforeLoop = loop.previousStatement() //TODO: support initialization not right before the loop + + if (statementBeforeLoop == variable) { + val initializer = variable.initializer ?: return null + return VariableInitialization(variable, variable, initializer) + } + + val assignment = statementBeforeLoop?.asAssignment() ?: return null + if (!assignment.left.isVariableReference(variable)) return null + val initializer = assignment.right ?: return null + return VariableInitialization(variable, assignment, initializer) } diff --git a/idea/testData/intentions/loopToCallChain/firstOrNull_assignmentInitialization.kt b/idea/testData/intentions/loopToCallChain/firstOrNull_assignmentInitialization.kt new file mode 100644 index 00000000000..2303fc20329 --- /dev/null +++ b/idea/testData/intentions/loopToCallChain/firstOrNull_assignmentInitialization.kt @@ -0,0 +1,12 @@ +// WITH_RUNTIME +fun foo(list: List) { + var result: String? = "" + + result = null + for (s in list) { + if (s.length > 0) { + result = s + break + } + } +} \ No newline at end of file diff --git a/idea/testData/intentions/loopToCallChain/firstOrNull_assignmentInitialization.kt.after b/idea/testData/intentions/loopToCallChain/firstOrNull_assignmentInitialization.kt.after new file mode 100644 index 00000000000..e1ae7ae8556 --- /dev/null +++ b/idea/testData/intentions/loopToCallChain/firstOrNull_assignmentInitialization.kt.after @@ -0,0 +1,6 @@ +// WITH_RUNTIME +fun foo(list: List) { + var result: String? = "" + + result = list.firstOrNull { it.length > 0 } +} \ No newline at end of file