More relaxed checks for any() with return

This commit is contained in:
Valentin Kipyatkov
2016-04-06 12:42:20 +03:00
parent ff0bb4fbb8
commit 14ef93a797
4 changed files with 24 additions and 4 deletions
@@ -18,11 +18,14 @@ package org.jetbrains.kotlin.idea.intentions.loopToCallChain.result
import com.intellij.psi.search.LocalSearchScope
import com.intellij.psi.search.searches.ReferencesSearch
import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.intentions.loopToCallChain.*
import org.jetbrains.kotlin.idea.intentions.loopToCallChain.sequence.FilterTransformation
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.PsiChildRange
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
class FindAndAssignTransformation(
private val loop: KtForExpression,
@@ -101,6 +104,9 @@ class FindAndAssignTransformation(
val usageCountInLoop = ReferencesSearch.search(declarationBeforeLoop, LocalSearchScope(state.outerLoop)).count()
if (usageCountInLoop != 1) return null // this should be the only usage of this variable inside the loop
// we do not try to convert anything if the initializer is not compile-time constant because of possible side-effects
if (ConstantExpressionEvaluator.getConstant(initializer, initializer.analyze(BodyResolveMode.PARTIAL)) == null) return null
val generator = buildFindOperationGenerator(right, initializer, state.workingVariable, findFirst) ?: return null
val transformation = FindAndAssignTransformation(state.outerLoop, state.workingVariable, generator, declarationBeforeLoop)
@@ -158,16 +158,13 @@ fun buildFindOperationGenerator(
}
}
// initial value is compile-time constant
ConstantExpressionEvaluator.getConstant(valueIfNotFound, valueIfNotFound.analyze(BodyResolveMode.PARTIAL)) != null -> {
else -> {
return { chainedCallGenerator, filter ->
val chainedCall = generateChainedCall("any", chainedCallGenerator, filter)
KtPsiFactory(chainedCall).createExpressionByPattern("if ($0) $1 else $2", chainedCall, valueIfFound, valueIfNotFound)
}
}
else -> return null
}
return { chainedCallGenerator, filter -> generateChainedCall(stdlibFunName, chainedCallGenerator, filter) }
@@ -0,0 +1,11 @@
// WITH_RUNTIME
fun foo(list: List<String>): Int {
<caret>for (s in list) {
if (s.length > 0) {
return -1
}
}
return takeInt()
}
fun takeInt(): Int = 0
@@ -0,0 +1,6 @@
// WITH_RUNTIME
fun foo(list: List<String>): Int {
<caret>return if (list.any { it.length > 0 }) -1 else takeInt()
}
fun takeInt(): Int = 0