From c2103e2200996d6b9547f10bf92c4c3b84e0d9a9 Mon Sep 17 00:00:00 2001 From: Valentin Kipyatkov Date: Fri, 22 Apr 2016 22:44:42 +0300 Subject: [PATCH] Supported indexOf/lastIndexOf --- .../result/FindTransformationMatcher.kt | 52 +++++++++++++------ .../intentions/loopToCallChain/indexOf.kt | 10 ++++ .../loopToCallChain/indexOf.kt.after | 5 ++ .../intentions/loopToCallChain/lastIndexOf.kt | 10 ++++ .../loopToCallChain/lastIndexOf.kt.after | 5 ++ 5 files changed, 65 insertions(+), 17 deletions(-) create mode 100644 idea/testData/intentions/loopToCallChain/indexOf.kt create mode 100644 idea/testData/intentions/loopToCallChain/indexOf.kt.after create mode 100644 idea/testData/intentions/loopToCallChain/lastIndexOf.kt create mode 100644 idea/testData/intentions/loopToCallChain/lastIndexOf.kt.after diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/loopToCallChain/result/FindTransformationMatcher.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/loopToCallChain/result/FindTransformationMatcher.kt index 6c30e898cf3..0ee81f9f444 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/loopToCallChain/result/FindTransformationMatcher.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/loopToCallChain/result/FindTransformationMatcher.kt @@ -177,13 +177,14 @@ object FindTransformationMatcher : TransformationMatcher { private class SimpleGenerator( override val functionName: String, private val inputVariable: KtCallableDeclaration, - private val filter: KtExpression? + private val filter: KtExpression?, + private val argument: KtExpression? = null ) : FindOperationGenerator { override val hasFilter: Boolean get() = filter != null override fun generate(chainedCallGenerator: ChainedCallGenerator): KtExpression { - return generateChainedCall(functionName, chainedCallGenerator, inputVariable, filter) + return generateChainedCall(functionName, chainedCallGenerator, inputVariable, filter, argument) } } @@ -191,14 +192,25 @@ object FindTransformationMatcher : TransformationMatcher { stdlibFunName: String, chainedCallGenerator: ChainedCallGenerator, inputVariable: KtCallableDeclaration, - filter: KtExpression? + filter: KtExpression?, + argument: KtExpression? = null ): KtExpression { return if (filter == null) { - chainedCallGenerator.generate("$stdlibFunName()") + if (argument != null) { + chainedCallGenerator.generate("$stdlibFunName($0)", argument) + } + else { + chainedCallGenerator.generate("$stdlibFunName()") + } } else { val lambda = generateLambda(inputVariable, filter) - chainedCallGenerator.generate("$stdlibFunName $0:'{}'", lambda) + if (argument != null) { + chainedCallGenerator.generate("$stdlibFunName($0) $1:'{}'", argument, lambda) + } + else { + chainedCallGenerator.generate("$stdlibFunName $0:'{}'", lambda) + } } } @@ -222,8 +234,15 @@ object FindTransformationMatcher : TransformationMatcher { //TODO: what if value when not found is not "-1"? if (valueIfFound.isVariableReference(indexVariable) && valueIfNotFound.text == "-1") { - val functionName = if (findFirst) "indexOfFirst" else "indexOfLast" - return SimpleGenerator(functionName, inputVariable, filter) + val containsArgument = filter!!.isFilterForContainsOperation(inputVariable, loop) + if (containsArgument != null) { + val functionName = if (findFirst) "indexOf" else "lastIndexOf" + return SimpleGenerator(functionName, inputVariable, null, containsArgument) + } + else { + val functionName = if (findFirst) "indexOfFirst" else "indexOfLast" + return SimpleGenerator(functionName, inputVariable, filter) + } } return null @@ -331,18 +350,17 @@ object FindTransformationMatcher : TransformationMatcher { if (filter != null) { val containsArgument = filter.isFilterForContainsOperation(inputVariable, loop) if (containsArgument != null) { - return object: FindOperationGenerator { - override val functionName: String - get() = "contains" - - override val hasFilter: Boolean - get() = false - - override fun generate(chainedCallGenerator: ChainedCallGenerator): KtExpression { - val expression = chainedCallGenerator.generate("contains($0)", containsArgument) - return if (negated) expression.negate() else expression + val generator = SimpleGenerator("contains", inputVariable, null, containsArgument) + if (negated) { + return object: FindOperationGenerator by generator{ + override fun generate(chainedCallGenerator: ChainedCallGenerator): KtExpression { + return generator.generate(chainedCallGenerator).negate() + } } } + else { + return generator + } } } diff --git a/idea/testData/intentions/loopToCallChain/indexOf.kt b/idea/testData/intentions/loopToCallChain/indexOf.kt new file mode 100644 index 00000000000..3572beb82a3 --- /dev/null +++ b/idea/testData/intentions/loopToCallChain/indexOf.kt @@ -0,0 +1,10 @@ +// WITH_RUNTIME +// INTENTION_TEXT: "Replace with 'indexOf()'" +fun foo(list: List): Int { + for ((index, s) in list.withIndex()) { + if (s == "a") { + return index + } + } + return -1 +} \ No newline at end of file diff --git a/idea/testData/intentions/loopToCallChain/indexOf.kt.after b/idea/testData/intentions/loopToCallChain/indexOf.kt.after new file mode 100644 index 00000000000..b9e552099e2 --- /dev/null +++ b/idea/testData/intentions/loopToCallChain/indexOf.kt.after @@ -0,0 +1,5 @@ +// WITH_RUNTIME +// INTENTION_TEXT: "Replace with 'indexOf()'" +fun foo(list: List): Int { + return list.indexOf("a") +} \ No newline at end of file diff --git a/idea/testData/intentions/loopToCallChain/lastIndexOf.kt b/idea/testData/intentions/loopToCallChain/lastIndexOf.kt new file mode 100644 index 00000000000..4c8c42e36e6 --- /dev/null +++ b/idea/testData/intentions/loopToCallChain/lastIndexOf.kt @@ -0,0 +1,10 @@ +// WITH_RUNTIME +// INTENTION_TEXT: "Replace with 'lastIndexOf()'" +fun foo(list: List) { + var result = -1 + for ((index, s) in list.withIndex()) { + if (s == "a") { + result = index + } + } +} \ No newline at end of file diff --git a/idea/testData/intentions/loopToCallChain/lastIndexOf.kt.after b/idea/testData/intentions/loopToCallChain/lastIndexOf.kt.after new file mode 100644 index 00000000000..f6885843a8a --- /dev/null +++ b/idea/testData/intentions/loopToCallChain/lastIndexOf.kt.after @@ -0,0 +1,5 @@ +// WITH_RUNTIME +// INTENTION_TEXT: "Replace with 'lastIndexOf()'" +fun foo(list: List) { + val result = list.lastIndexOf("a") +} \ No newline at end of file