Supported "lastOrNull" and "any" without break in the loop
This commit is contained in:
+17
-4
@@ -70,16 +70,29 @@ class FindAndAssignTransformation(
|
|||||||
* variable = ...
|
* variable = ...
|
||||||
* break
|
* break
|
||||||
* }
|
* }
|
||||||
|
* or
|
||||||
|
* val variable = ...
|
||||||
|
* for (...) {
|
||||||
|
* ...
|
||||||
|
* variable = ...
|
||||||
|
* }
|
||||||
*/
|
*/
|
||||||
object Matcher : ResultTransformationMatcher {
|
object Matcher : ResultTransformationMatcher {
|
||||||
override fun match(state: MatchingState): ResultTransformationMatch? {
|
override fun match(state: MatchingState): ResultTransformationMatch? {
|
||||||
//TODO: pass indexVariable as null if not used
|
//TODO: pass indexVariable as null if not used
|
||||||
if (state.indexVariable != null) return null
|
if (state.indexVariable != null) return null
|
||||||
|
|
||||||
if (state.statements.size != 2) return null
|
when (state.statements.size) {
|
||||||
|
1 -> {}
|
||||||
|
|
||||||
val breakExpression = state.statements.last() as? KtBreakExpression ?: return null
|
2 -> {
|
||||||
if (!breakExpression.isBreakOrContinueOfLoop(state.outerLoop)) return null
|
val breakExpression = state.statements.last() as? KtBreakExpression ?: return null
|
||||||
|
if (!breakExpression.isBreakOrContinueOfLoop(state.outerLoop)) return null
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> return null
|
||||||
|
}
|
||||||
|
val findFirst = state.statements.size == 2
|
||||||
|
|
||||||
val binaryExpression = state.statements.first() as? KtBinaryExpression ?: return null
|
val binaryExpression = state.statements.first() as? KtBinaryExpression ?: return null
|
||||||
if (binaryExpression.operationToken != KtTokens.EQ) return null
|
if (binaryExpression.operationToken != KtTokens.EQ) return null
|
||||||
@@ -94,7 +107,7 @@ class FindAndAssignTransformation(
|
|||||||
val usageCountInLoop = ReferencesSearch.search(declarationBeforeLoop, LocalSearchScope(state.outerLoop)).count()
|
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
|
if (usageCountInLoop != 1) return null // this should be the only usage of this variable inside the loop
|
||||||
|
|
||||||
val stdlibFunName = stdlibFunNameForFind(right, initializer, state.workingVariable) ?: return null
|
val stdlibFunName = stdlibFunNameForFind(right, initializer, state.workingVariable, findFirst) ?: return null
|
||||||
|
|
||||||
val transformation = FindAndAssignTransformation(state.outerLoop, state.workingVariable, stdlibFunName, declarationBeforeLoop)
|
val transformation = FindAndAssignTransformation(state.outerLoop, state.workingVariable, stdlibFunName, declarationBeforeLoop)
|
||||||
return ResultTransformationMatch(transformation)
|
return ResultTransformationMatch(transformation)
|
||||||
|
|||||||
+1
-1
@@ -78,7 +78,7 @@ class FindAndReturnTransformation(
|
|||||||
val returnValueInLoop = returnInLoop.returnedExpression ?: return null
|
val returnValueInLoop = returnInLoop.returnedExpression ?: return null
|
||||||
val returnValueAfterLoop = returnAfterLoop.returnedExpression ?: return null
|
val returnValueAfterLoop = returnAfterLoop.returnedExpression ?: return null
|
||||||
|
|
||||||
val stdlibFunName = stdlibFunNameForFind(returnValueInLoop, returnValueAfterLoop, state.workingVariable) ?: return null
|
val stdlibFunName = stdlibFunNameForFind(returnValueInLoop, returnValueAfterLoop, state.workingVariable, findFirst = true) ?: return null
|
||||||
|
|
||||||
val transformation = FindAndReturnTransformation(state.outerLoop, state.workingVariable, stdlibFunName, returnAfterLoop)
|
val transformation = FindAndReturnTransformation(state.outerLoop, state.workingVariable, stdlibFunName, returnAfterLoop)
|
||||||
return ResultTransformationMatch(transformation)
|
return ResultTransformationMatch(transformation)
|
||||||
|
|||||||
@@ -95,9 +95,9 @@ fun KtProperty.hasWriteUsages(): Boolean {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun stdlibFunNameForFind(valueIfFound: KtExpression, valueIfNotFound: KtExpression, workingVariable: KtCallableDeclaration): String? {
|
fun stdlibFunNameForFind(valueIfFound: KtExpression, valueIfNotFound: KtExpression, workingVariable: KtCallableDeclaration, findFirst: Boolean): String? {
|
||||||
return when {
|
return when {
|
||||||
valueIfNotFound.isNullExpression() && valueIfFound.isVariableReference(workingVariable) -> "firstOrNull"
|
valueIfNotFound.isNullExpression() && valueIfFound.isVariableReference(workingVariable) -> if (findFirst) "firstOrNull" else "lastOrNull"
|
||||||
|
|
||||||
valueIfFound.isTrueConstant() && valueIfNotFound.isFalseConstant() -> "any"
|
valueIfFound.isTrueConstant() && valueIfNotFound.isFalseConstant() -> "any"
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
fun foo(list: List<String>) {
|
||||||
|
var found = false
|
||||||
|
<caret>for (s in list) {
|
||||||
|
if (s.length > 0) {
|
||||||
|
found = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
fun foo(list: List<String>) {
|
||||||
|
<caret>val found = list.any { it.length > 0 }
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
fun foo(list: List<String>) {
|
||||||
|
var result: String? = null
|
||||||
|
<caret>for (s in list) {
|
||||||
|
if (s.length > 0) {
|
||||||
|
result = s
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
fun foo(list: List<String>) {
|
||||||
|
<caret>val result: String? = list.lastOrNull { it.length > 0 }
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user