Split or glue together checks for not null and is instance + more intelligent use of filter vs filterTo
#KT-14284 Fixed #KT-14286 Fixed #KT-14287 Fixed #KT-14303 Fixed
This commit is contained in:
@@ -22,7 +22,6 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyzeAndGetResult
|
||||
import org.jetbrains.kotlin.idea.core.ShortenReferences
|
||||
import org.jetbrains.kotlin.idea.references.mainReference
|
||||
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
|
||||
@@ -164,8 +163,8 @@ private fun KtExpression.specialNegation(): KtExpression? {
|
||||
if (operationReference.getReferencedName() == "!") {
|
||||
val baseExpression = baseExpression
|
||||
if (baseExpression != null) {
|
||||
val context = baseExpression.analyzeAndGetResult().bindingContext
|
||||
val type = context.getType(baseExpression)
|
||||
val bindingContext = baseExpression.analyze(BodyResolveMode.PARTIAL)
|
||||
val type = bindingContext.getType(baseExpression)
|
||||
if (type != null && KotlinBuiltIns.isBoolean(type)) {
|
||||
return KtPsiUtil.safeDeparenthesize(baseExpression)
|
||||
}
|
||||
|
||||
+18
-16
@@ -22,11 +22,7 @@ import org.jetbrains.kotlin.descriptors.VariableDescriptor
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor
|
||||
import org.jetbrains.kotlin.idea.imports.importableFqName
|
||||
import org.jetbrains.kotlin.idea.intentions.loopToCallChain.*
|
||||
import org.jetbrains.kotlin.idea.intentions.loopToCallChain.sequence.FilterNotNullTransformation
|
||||
import org.jetbrains.kotlin.idea.intentions.loopToCallChain.sequence.FilterTransformation
|
||||
import org.jetbrains.kotlin.idea.intentions.loopToCallChain.sequence.FlatMapTransformation
|
||||
import org.jetbrains.kotlin.idea.intentions.loopToCallChain.sequence.MapTransformation
|
||||
import org.jetbrains.kotlin.idea.intentions.negate
|
||||
import org.jetbrains.kotlin.idea.intentions.loopToCallChain.sequence.*
|
||||
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
@@ -41,7 +37,9 @@ class AddToCollectionTransformation(
|
||||
override fun mergeWithPrevious(previousTransformation: SequenceTransformation): ResultTransformation? {
|
||||
return when (previousTransformation) {
|
||||
is FilterTransformation -> {
|
||||
FilterToTransformation.create(loop, previousTransformation.inputVariable, previousTransformation.indexVariable, targetCollection, previousTransformation.condition, previousTransformation.isInverse)
|
||||
FilterToTransformation.create(
|
||||
loop, previousTransformation.inputVariable, previousTransformation.indexVariable,
|
||||
targetCollection, previousTransformation.effectiveCondition, previousTransformation.isFilterNot)
|
||||
}
|
||||
|
||||
is FilterNotNullTransformation -> {
|
||||
@@ -201,15 +199,19 @@ class FilterToTransformation private constructor(
|
||||
private val inputVariable: KtCallableDeclaration,
|
||||
private val indexVariable: KtCallableDeclaration?,
|
||||
private val targetCollection: KtExpression,
|
||||
private val condition: KtExpression,
|
||||
private val isInverse: Boolean
|
||||
private val effectiveCondition: Condition,
|
||||
private val isFilterNot: Boolean
|
||||
) : ReplaceLoopResultTransformation(loop) {
|
||||
|
||||
private fun effectiveCondition() = if (isInverse) condition.negate() else condition
|
||||
init {
|
||||
if (isFilterNot) {
|
||||
assert(indexVariable == null)
|
||||
}
|
||||
}
|
||||
|
||||
private val functionName = when {
|
||||
indexVariable != null -> "filterIndexedTo"
|
||||
isInverse -> "filterNotTo"
|
||||
isFilterNot -> "filterNotTo"
|
||||
else -> "filterTo"
|
||||
}
|
||||
|
||||
@@ -218,9 +220,9 @@ class FilterToTransformation private constructor(
|
||||
|
||||
override fun generateCode(chainedCallGenerator: ChainedCallGenerator): KtExpression {
|
||||
val lambda = if (indexVariable != null)
|
||||
generateLambda(inputVariable, indexVariable, effectiveCondition())
|
||||
generateLambda(inputVariable, indexVariable, effectiveCondition.asExpression())
|
||||
else
|
||||
generateLambda(inputVariable, condition)
|
||||
generateLambda(inputVariable, if (isFilterNot) effectiveCondition.asNegatedExpression() else effectiveCondition.asExpression())
|
||||
return chainedCallGenerator.generate("$functionName($0) $1:'{}'", targetCollection, lambda)
|
||||
}
|
||||
|
||||
@@ -230,16 +232,16 @@ class FilterToTransformation private constructor(
|
||||
inputVariable: KtCallableDeclaration,
|
||||
indexVariable: KtCallableDeclaration?,
|
||||
targetCollection: KtExpression,
|
||||
condition: KtExpression,
|
||||
isInverse: Boolean
|
||||
condition: Condition,
|
||||
isFilterNot: Boolean
|
||||
): ResultTransformation {
|
||||
val initialization = targetCollection.findVariableInitializationBeforeLoop(loop, checkNoOtherUsagesInLoop = true)
|
||||
if (initialization != null && initialization.initializer.hasNoSideEffect()) {
|
||||
val transformation = FilterToTransformation(loop, inputVariable, indexVariable, initialization.initializer, condition, isInverse)
|
||||
val transformation = FilterToTransformation(loop, inputVariable, indexVariable, initialization.initializer, condition, isFilterNot)
|
||||
return AssignToVariableResultTransformation.createDelegated(transformation, initialization)
|
||||
}
|
||||
else {
|
||||
return FilterToTransformation(loop, inputVariable, indexVariable, targetCollection, condition, isInverse)
|
||||
return FilterToTransformation(loop, inputVariable, indexVariable, targetCollection, condition, isFilterNot)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -34,9 +34,9 @@ class CountTransformation(
|
||||
if (previousTransformation !is FilterTransformationBase) return null
|
||||
if (previousTransformation.indexVariable != null) return null
|
||||
val newFilter = if (filter == null)
|
||||
previousTransformation.effectiveCondition
|
||||
previousTransformation.effectiveCondition.asExpression()
|
||||
else
|
||||
KtPsiFactory(filter).createExpressionByPattern("$0 && $1", previousTransformation.effectiveCondition, filter)
|
||||
KtPsiFactory(filter).createExpressionByPattern("$0 && $1", previousTransformation.effectiveCondition.asExpression(), filter)
|
||||
return CountTransformation(loop, previousTransformation.inputVariable, initialization, newFilter)
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -225,7 +225,7 @@ object FindTransformationMatcher : TransformationMatcher {
|
||||
assert(valueIfFound.isPhysical)
|
||||
assert(valueIfNotFound.isPhysical)
|
||||
|
||||
val filter = filterTransformation?.effectiveCondition
|
||||
val filter = filterTransformation?.effectiveCondition?.asExpression()
|
||||
|
||||
if (indexVariable != null) {
|
||||
if (filterTransformation == null) return null // makes no sense, indexVariable must be always null
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.intentions.loopToCallChain.sequence
|
||||
|
||||
import org.jetbrains.kotlin.idea.intentions.loopToCallChain.hasUsages
|
||||
import org.jetbrains.kotlin.idea.intentions.negate
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
|
||||
interface Condition {
|
||||
fun asExpression(): KtExpression
|
||||
fun asNegatedExpression(): KtExpression
|
||||
fun toAtomicConditions(): List<AtomicCondition>
|
||||
|
||||
companion object {
|
||||
fun create(expression: KtExpression, negated: Boolean = false): Condition {
|
||||
if (negated) {
|
||||
if (expression is KtBinaryExpression && expression.operationToken == KtTokens.OROR) {
|
||||
//TODO: check Boolean type for operands
|
||||
val left = expression.left
|
||||
val right = expression.right
|
||||
if (left != null && right != null) {
|
||||
val leftCondition = create(left, negated = true)
|
||||
val rightCondition = create(right, negated = true)
|
||||
return CompositeCondition.create(leftCondition.toAtomicConditions() + rightCondition.toAtomicConditions())
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (expression is KtBinaryExpression && expression.operationToken == KtTokens.ANDAND) {
|
||||
//TODO: check Boolean type for operands
|
||||
val left = expression.left
|
||||
val right = expression.right
|
||||
if (left != null && right != null) {
|
||||
val leftCondition = create(left)
|
||||
val rightCondition = create(right)
|
||||
return CompositeCondition.create(leftCondition.toAtomicConditions() + rightCondition.toAtomicConditions())
|
||||
}
|
||||
}
|
||||
}
|
||||
return AtomicCondition(expression, negated)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class AtomicCondition(val expression: KtExpression, val isNegated: Boolean = false) : Condition {
|
||||
init {
|
||||
assert(expression.isPhysical)
|
||||
}
|
||||
|
||||
override fun asExpression() = if (isNegated) expression.negate() else expression
|
||||
override fun asNegatedExpression() = if (isNegated) expression else expression.negate()
|
||||
override fun toAtomicConditions() = listOf(this)
|
||||
|
||||
fun negate() = AtomicCondition(expression, !isNegated)
|
||||
}
|
||||
|
||||
class CompositeCondition private constructor(val conditions: List<AtomicCondition>) : Condition {
|
||||
override fun asExpression(): KtExpression {
|
||||
val factory = KtPsiFactory(conditions.first().expression)
|
||||
return factory.buildExpression {
|
||||
for ((index, condition) in conditions.withIndex()) {
|
||||
if (index > 0) {
|
||||
appendFixedText("&&")
|
||||
}
|
||||
appendExpression(condition.asExpression())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun asNegatedExpression(): KtExpression {
|
||||
return asExpression().negate() //TODO?
|
||||
}
|
||||
|
||||
override fun toAtomicConditions() = conditions
|
||||
|
||||
companion object {
|
||||
fun create(conditions: List<AtomicCondition>): Condition {
|
||||
return conditions.singleOrNull() ?: CompositeCondition(conditions)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun Condition.hasUsagesOf(variable: KtCallableDeclaration): Boolean {
|
||||
return toAtomicConditions().any { variable.hasUsages(it.expression) }
|
||||
}
|
||||
|
||||
+121
-61
@@ -16,17 +16,25 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.intentions.loopToCallChain.sequence
|
||||
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.isNullExpression
|
||||
import org.jetbrains.kotlin.idea.intentions.loopToCallChain.*
|
||||
import org.jetbrains.kotlin.idea.intentions.loopToCallChain.result.FindTransformationMatcher
|
||||
import org.jetbrains.kotlin.idea.intentions.loopToCallChain.result.MaxOrMinTransformation
|
||||
import org.jetbrains.kotlin.idea.intentions.negate
|
||||
import org.jetbrains.kotlin.idea.references.mainReference
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.anyDescendantOfType
|
||||
import org.jetbrains.kotlin.psi.psiUtil.blockExpressionsOrSingle
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.singletonList
|
||||
import java.util.*
|
||||
|
||||
abstract class FilterTransformationBase : SequenceTransformation {
|
||||
abstract val effectiveCondition: KtExpression
|
||||
abstract val effectiveCondition: Condition
|
||||
|
||||
abstract val inputVariable: KtCallableDeclaration
|
||||
abstract val indexVariable: KtCallableDeclaration?
|
||||
|
||||
@@ -66,31 +74,75 @@ abstract class FilterTransformationBase : SequenceTransformation {
|
||||
var (transformation, currentState) = matchOneTransformation(state) ?: return null
|
||||
assert(currentState.indexVariable == state.indexVariable) // indexVariable should not change
|
||||
|
||||
if (transformation is FilterTransformation) {
|
||||
while (true) {
|
||||
currentState = currentState.unwrapBlock()
|
||||
if (transformation !is FilterTransformationBase) {
|
||||
return TransformationMatch.Sequence(transformation, currentState)
|
||||
}
|
||||
|
||||
if (MaxOrMinTransformation.Matcher.match(currentState) != null) break // do not take 'if' which is required for min/max matcher
|
||||
val atomicConditions = transformation.effectiveCondition.toAtomicConditions().toMutableList()
|
||||
while (true) {
|
||||
currentState = currentState.unwrapBlock()
|
||||
|
||||
val (nextTransformation, nextState) = matchOneTransformation(currentState) ?: break
|
||||
if (nextTransformation !is FilterTransformation) break
|
||||
assert(nextState.indexVariable == currentState.indexVariable) // indexVariable should not change
|
||||
if (MaxOrMinTransformation.Matcher.match(currentState) != null) break // do not take 'if' which is required for min/max matcher
|
||||
|
||||
val indexVariable = transformation.indexVariable ?: nextTransformation.indexVariable
|
||||
val mergedCondition = KtPsiFactory(state.outerLoop).createExpressionByPattern(
|
||||
"$0 && $1", transformation.effectiveCondition, nextTransformation.effectiveCondition)
|
||||
transformation = FilterTransformation(state.outerLoop, transformation.inputVariable, indexVariable, mergedCondition, isInverse = false) //TODO: build filterNot in some cases?
|
||||
currentState = nextState
|
||||
val (nextTransformation, nextState) = matchOneTransformation(currentState) ?: break
|
||||
if (nextTransformation !is FilterTransformationBase) break
|
||||
assert(nextState.indexVariable == currentState.indexVariable) // indexVariable should not change
|
||||
|
||||
atomicConditions.addAll(nextTransformation.effectiveCondition.toAtomicConditions())
|
||||
|
||||
currentState = nextState
|
||||
}
|
||||
|
||||
val transformations = createTransformationsByAtomicConditions(
|
||||
currentState.outerLoop,
|
||||
currentState.inputVariable,
|
||||
currentState.indexVariable,
|
||||
atomicConditions,
|
||||
currentState.statements)
|
||||
assert(transformations.isNotEmpty())
|
||||
|
||||
val findTransformationMatch = FindTransformationMatcher.matchWithFilterBefore(currentState, transformations.last())
|
||||
if (findTransformationMatch != null) {
|
||||
return TransformationMatch.Result(findTransformationMatch.resultTransformation,
|
||||
transformations.dropLast(1) + findTransformationMatch.sequenceTransformations)
|
||||
}
|
||||
else {
|
||||
return TransformationMatch.Sequence(transformations, currentState)
|
||||
}
|
||||
}
|
||||
|
||||
private fun createTransformationsByAtomicConditions(
|
||||
loop: KtForExpression,
|
||||
inputVariable: KtCallableDeclaration,
|
||||
indexVariable: KtCallableDeclaration?,
|
||||
conditions: List<AtomicCondition>,
|
||||
restStatements: List<KtExpression>
|
||||
): List<FilterTransformationBase> {
|
||||
//TODO: indexVariable case
|
||||
|
||||
if (conditions.size == 1) {
|
||||
return createFilterTransformation(loop, inputVariable, indexVariable, conditions.single()).singletonList()
|
||||
}
|
||||
|
||||
val transformations = ArrayList<FilterTransformationBase>()
|
||||
for (condition in conditions) {
|
||||
val transformation = createFilterTransformation(loop, inputVariable, indexVariable, condition)
|
||||
if (transformation !is FilterTransformation && isSmartCastUsed(inputVariable, restStatements)) { // filterIsInstance of filterNotNull
|
||||
transformations.add(transformation)
|
||||
}
|
||||
else {
|
||||
val prevFilter = transformations.lastOrNull() as? FilterTransformation
|
||||
if (prevFilter != null) {
|
||||
val mergedCondition = CompositeCondition.create(prevFilter.effectiveCondition.toAtomicConditions() + transformation.effectiveCondition.toAtomicConditions())
|
||||
val mergedTransformation = createFilterTransformation(loop, inputVariable, indexVariable, mergedCondition, onlyFilterOrFilterNot = true)
|
||||
transformations[transformations.lastIndex] = mergedTransformation
|
||||
}
|
||||
else {
|
||||
transformations.add(createFilterTransformation(loop, inputVariable, indexVariable, condition, onlyFilterOrFilterNot = true))
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (transformation is FilterTransformationBase) {
|
||||
FindTransformationMatcher.matchWithFilterBefore(currentState, transformation)
|
||||
?.let { return it }
|
||||
}
|
||||
|
||||
return TransformationMatch.Sequence(transformation, currentState)
|
||||
return transformations
|
||||
}
|
||||
|
||||
private fun matchOneTransformation(state: MatchingState): Pair<SequenceTransformation, MatchingState>? {
|
||||
@@ -104,7 +156,7 @@ abstract class FilterTransformationBase : SequenceTransformation {
|
||||
if (!state.inputVariable.hasUsages(condition) && (state.indexVariable == null || !state.indexVariable.hasUsages(condition))) return null
|
||||
|
||||
if (state.statements.size == 1) {
|
||||
val transformation = createFilterTransformation(state.outerLoop, state.inputVariable, state.indexVariable, condition, isInverse = false)
|
||||
val transformation = createFilterTransformation(state.outerLoop, state.inputVariable, state.indexVariable, Condition.create(condition))
|
||||
val newState = state.copy(statements = listOf(then))
|
||||
return transformation to newState
|
||||
}
|
||||
@@ -113,7 +165,7 @@ abstract class FilterTransformationBase : SequenceTransformation {
|
||||
when (statement) {
|
||||
is KtContinueExpression -> {
|
||||
if (statement.targetLoop() != state.innerLoop) return null
|
||||
val transformation = createFilterTransformation(state.outerLoop, state.inputVariable, state.indexVariable, condition, isInverse = true)
|
||||
val transformation = createFilterTransformation(state.outerLoop, state.inputVariable, state.indexVariable, Condition.create(condition, negated = true))
|
||||
val newState = state.copy(statements = state.statements.drop(1))
|
||||
return transformation to newState
|
||||
}
|
||||
@@ -130,40 +182,52 @@ abstract class FilterTransformationBase : SequenceTransformation {
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: choose filter or filterNot depending on condition
|
||||
private fun createFilterTransformation(
|
||||
loop: KtForExpression,
|
||||
inputVariable: KtCallableDeclaration,
|
||||
indexVariable: KtCallableDeclaration?,
|
||||
condition: KtExpression,
|
||||
isInverse: Boolean
|
||||
condition: Condition,
|
||||
onlyFilterOrFilterNot: Boolean = false
|
||||
): FilterTransformationBase {
|
||||
|
||||
val effectiveCondition = if (isInverse) condition.negate() else condition
|
||||
|
||||
if (indexVariable != null && indexVariable.hasUsages(condition)) {
|
||||
return FilterTransformation(loop, inputVariable, indexVariable, effectiveCondition, isInverse = false)
|
||||
if (indexVariable != null && condition.hasUsagesOf(indexVariable)) {
|
||||
return FilterTransformation(loop, inputVariable, indexVariable, condition, isFilterNot = false)
|
||||
}
|
||||
|
||||
if (effectiveCondition is KtIsExpression
|
||||
&& !effectiveCondition.isNegated
|
||||
&& effectiveCondition.leftHandSide.isSimpleName(inputVariable.nameAsSafeName) // we cannot use isVariableReference here because expression can be non-physical
|
||||
) {
|
||||
val typeRef = effectiveCondition.typeReference
|
||||
if (typeRef != null) {
|
||||
return FilterIsInstanceTransformation(loop, inputVariable, typeRef)
|
||||
val conditionAsExpression = condition.asExpression()
|
||||
if (!onlyFilterOrFilterNot) {
|
||||
if (conditionAsExpression is KtIsExpression
|
||||
&& !conditionAsExpression.isNegated
|
||||
&& conditionAsExpression.leftHandSide.isSimpleName(inputVariable.nameAsSafeName) // we cannot use isVariableReference here because expression can be non-physical
|
||||
) {
|
||||
val typeRef = conditionAsExpression.typeReference
|
||||
if (typeRef != null) {
|
||||
return FilterIsInstanceTransformation(loop, inputVariable, typeRef, condition)
|
||||
}
|
||||
}
|
||||
|
||||
if (conditionAsExpression is KtBinaryExpression
|
||||
&& conditionAsExpression.operationToken == KtTokens.EXCLEQ
|
||||
&& conditionAsExpression.right.isNullExpression()
|
||||
&& conditionAsExpression.left.isSimpleName(inputVariable.nameAsSafeName)
|
||||
) {
|
||||
return FilterNotNullTransformation(loop, inputVariable, condition)
|
||||
}
|
||||
}
|
||||
|
||||
if (effectiveCondition is KtBinaryExpression
|
||||
&& effectiveCondition.operationToken == KtTokens.EXCLEQ
|
||||
&& effectiveCondition.right.isNullExpression()
|
||||
&& effectiveCondition.left.isSimpleName(inputVariable.nameAsSafeName)
|
||||
) {
|
||||
return FilterNotNullTransformation(loop, inputVariable)
|
||||
if (conditionAsExpression is KtPrefixExpression && conditionAsExpression.operationToken == KtTokens.EXCL) {
|
||||
return FilterTransformation(loop, inputVariable, null, condition, isFilterNot = true)
|
||||
}
|
||||
|
||||
return FilterTransformation(loop, inputVariable, null, condition, isInverse)
|
||||
return FilterTransformation(loop, inputVariable, null, condition, isFilterNot = false)
|
||||
}
|
||||
|
||||
private fun isSmartCastUsed(inputVariable: KtCallableDeclaration, statements: List<KtExpression>): Boolean {
|
||||
return statements.any { statement ->
|
||||
statement.anyDescendantOfType<KtNameReferenceExpression> {
|
||||
it.mainReference.resolve() == inputVariable && it.analyze(BodyResolveMode.PARTIAL)[BindingContext.SMARTCAST, it] != null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -172,17 +236,19 @@ class FilterTransformation(
|
||||
override val loop: KtForExpression,
|
||||
override val inputVariable: KtCallableDeclaration,
|
||||
override val indexVariable: KtCallableDeclaration?,
|
||||
val condition: KtExpression,
|
||||
val isInverse: Boolean
|
||||
override val effectiveCondition: Condition,
|
||||
val isFilterNot: Boolean
|
||||
) : FilterTransformationBase() {
|
||||
|
||||
override val effectiveCondition: KtExpression by lazy {
|
||||
if (isInverse) condition.negate() else condition
|
||||
init {
|
||||
if (isFilterNot) {
|
||||
assert(indexVariable == null)
|
||||
}
|
||||
}
|
||||
|
||||
private val functionName = when {
|
||||
indexVariable != null -> "filterIndexed"
|
||||
isInverse -> "filterNot"
|
||||
isFilterNot -> "filterNot"
|
||||
else -> "filter"
|
||||
}
|
||||
|
||||
@@ -191,9 +257,9 @@ class FilterTransformation(
|
||||
|
||||
override fun generateCode(chainedCallGenerator: ChainedCallGenerator): KtExpression {
|
||||
val lambda = if (indexVariable != null)
|
||||
generateLambda(inputVariable, indexVariable, effectiveCondition)
|
||||
generateLambda(inputVariable, indexVariable, effectiveCondition.asExpression())
|
||||
else
|
||||
generateLambda(inputVariable, condition)
|
||||
generateLambda(inputVariable, if (isFilterNot) effectiveCondition.asNegatedExpression() else effectiveCondition.asExpression())
|
||||
return chainedCallGenerator.generate("$0$1:'{}'", functionName, lambda)
|
||||
}
|
||||
}
|
||||
@@ -201,13 +267,10 @@ class FilterTransformation(
|
||||
class FilterIsInstanceTransformation(
|
||||
override val loop: KtForExpression,
|
||||
override val inputVariable: KtCallableDeclaration,
|
||||
private val type: KtTypeReference
|
||||
private val type: KtTypeReference,
|
||||
override val effectiveCondition: Condition
|
||||
) : FilterTransformationBase() {
|
||||
|
||||
override val effectiveCondition by lazy {
|
||||
KtPsiFactory(loop).createExpressionByPattern("$0 is $1", inputVariable.nameAsSafeName, type)
|
||||
}
|
||||
|
||||
override val indexVariable: KtCallableDeclaration? get() = null
|
||||
|
||||
override val presentation: String
|
||||
@@ -220,13 +283,10 @@ class FilterIsInstanceTransformation(
|
||||
|
||||
class FilterNotNullTransformation(
|
||||
override val loop: KtForExpression,
|
||||
override val inputVariable: KtCallableDeclaration
|
||||
override val inputVariable: KtCallableDeclaration,
|
||||
override val effectiveCondition: Condition
|
||||
) : FilterTransformationBase() {
|
||||
|
||||
override val effectiveCondition: KtExpression by lazy {
|
||||
KtPsiFactory(loop).createExpressionByPattern("$0 != null", inputVariable.nameAsSafeName)
|
||||
}
|
||||
|
||||
override val indexVariable: KtCallableDeclaration? get() = null
|
||||
|
||||
override fun mergeWithPrevious(previousTransformation: SequenceTransformation): SequenceTransformation? {
|
||||
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
// WITH_RUNTIME
|
||||
// INTENTION_TEXT: "Replace with 'filterIndexedTo(){}'"
|
||||
// IS_APPLICABLE_2: false
|
||||
fun foo(list: List<Any>, out: MutableList<Any>){
|
||||
<caret>for ((i, any) in list.withIndex()) {
|
||||
if (any is String && i % 2 == 0)
|
||||
out.add(any)
|
||||
}
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
// WITH_RUNTIME
|
||||
// INTENTION_TEXT: "Replace with 'filterIndexedTo(){}'"
|
||||
// IS_APPLICABLE_2: false
|
||||
fun foo(list: List<Any>, out: MutableList<Any>){
|
||||
list.filterIndexedTo(out) { i, any -> any is String && i % 2 == 0 }
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
// WITH_RUNTIME
|
||||
// INTENTION_TEXT: "Replace with 'filter{}.forEach{}'"
|
||||
// INTENTION_TEXT_2: "Replace with 'asSequence().filter{}.forEach{}'"
|
||||
fun foo(list: List<String?>){
|
||||
<caret>for (l in list) {
|
||||
if (l != null && l.startsWith("IMG:"))
|
||||
println(l)
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
// WITH_RUNTIME
|
||||
// INTENTION_TEXT: "Replace with 'filter{}.forEach{}'"
|
||||
// INTENTION_TEXT_2: "Replace with 'asSequence().filter{}.forEach{}'"
|
||||
fun foo(list: List<String?>){
|
||||
list
|
||||
.filter { it != null && it.startsWith("IMG:") }
|
||||
.forEach { println(it) }
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
// WITH_RUNTIME
|
||||
// INTENTION_TEXT: "Replace with 'filter{}.forEach{}'"
|
||||
// INTENTION_TEXT_2: "Replace with 'asSequence().filter{}.forEach{}'"
|
||||
fun foo(list: List<String?>){
|
||||
list
|
||||
.asSequence()
|
||||
.filter { it != null && it.startsWith("IMG:") }
|
||||
.forEach { println(it) }
|
||||
}
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
// WITH_RUNTIME
|
||||
// INTENTION_TEXT: "Replace with '...flatMap{}.filterNot{}.mapTo(){}'"
|
||||
// INTENTION_TEXT_2: "Replace with 'asSequence()...flatMap{}.filterNot{}.mapTo(){}'"
|
||||
// INTENTION_TEXT: "Replace with '...flatMap{}.filter{}.mapTo(){}'"
|
||||
// INTENTION_TEXT_2: "Replace with 'asSequence()...flatMap{}.filter{}.mapTo(){}'"
|
||||
fun foo(list: List<String>, target: MutableCollection<String>) {
|
||||
var i = 0
|
||||
<caret>for (s in list) {
|
||||
|
||||
Vendored
+3
-3
@@ -1,10 +1,10 @@
|
||||
// WITH_RUNTIME
|
||||
// INTENTION_TEXT: "Replace with '...flatMap{}.filterNot{}.mapTo(){}'"
|
||||
// INTENTION_TEXT_2: "Replace with 'asSequence()...flatMap{}.filterNot{}.mapTo(){}'"
|
||||
// INTENTION_TEXT: "Replace with '...flatMap{}.filter{}.mapTo(){}'"
|
||||
// INTENTION_TEXT_2: "Replace with 'asSequence()...flatMap{}.filter{}.mapTo(){}'"
|
||||
fun foo(list: List<String>, target: MutableCollection<String>) {
|
||||
<caret>list
|
||||
.filterIndexed { i, s -> i % 10 != 0 }
|
||||
.flatMap { it.indices }
|
||||
.filterNot { it == 10 }
|
||||
.filter { it != 10 }
|
||||
.mapTo(target) { it.toString() }
|
||||
}
|
||||
Vendored
+3
-3
@@ -1,11 +1,11 @@
|
||||
// WITH_RUNTIME
|
||||
// INTENTION_TEXT: "Replace with '...flatMap{}.filterNot{}.mapTo(){}'"
|
||||
// INTENTION_TEXT_2: "Replace with 'asSequence()...flatMap{}.filterNot{}.mapTo(){}'"
|
||||
// INTENTION_TEXT: "Replace with '...flatMap{}.filter{}.mapTo(){}'"
|
||||
// INTENTION_TEXT_2: "Replace with 'asSequence()...flatMap{}.filter{}.mapTo(){}'"
|
||||
fun foo(list: List<String>, target: MutableCollection<String>) {
|
||||
<caret>list
|
||||
.asSequence()
|
||||
.filterIndexed { i, s -> i % 10 != 0 }
|
||||
.flatMap { it.indices.asSequence() }
|
||||
.filterNot { it == 10 }
|
||||
.filter { it != 10 }
|
||||
.mapTo(target) { it.toString() }
|
||||
}
|
||||
@@ -3,7 +3,9 @@
|
||||
// IS_APPLICABLE_2: false
|
||||
fun foo(list: List<String>, target: MutableList<String>) {
|
||||
<caret>for (s in list) {
|
||||
if (s.length == 0) continue
|
||||
if (bar(s)) continue
|
||||
target.add(s)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun bar(string: String): Boolean = TODO()
|
||||
@@ -2,5 +2,7 @@
|
||||
// INTENTION_TEXT: "Replace with 'filterNotTo(){}'"
|
||||
// IS_APPLICABLE_2: false
|
||||
fun foo(list: List<String>, target: MutableList<String>) {
|
||||
<caret>list.filterNotTo(target) { it.length == 0 }
|
||||
}
|
||||
list.filterNotTo(target) { bar(it) }
|
||||
}
|
||||
|
||||
fun bar(string: String): Boolean = TODO()
|
||||
@@ -0,0 +1,10 @@
|
||||
// WITH_RUNTIME
|
||||
// INTENTION_TEXT: "Replace with 'filter{}.forEach{}'"
|
||||
// INTENTION_TEXT_2: "Replace with 'asSequence().filter{}.forEach{}'"
|
||||
fun foo(list: List<String?>){
|
||||
<caret>for (l in list) {
|
||||
if (l == null) continue
|
||||
if (l.startsWith("IMG:"))
|
||||
println(l)
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
// WITH_RUNTIME
|
||||
// INTENTION_TEXT: "Replace with 'filter{}.forEach{}'"
|
||||
// INTENTION_TEXT_2: "Replace with 'asSequence().filter{}.forEach{}'"
|
||||
fun foo(list: List<String?>){
|
||||
list
|
||||
.filter { it != null && it.startsWith("IMG:") }
|
||||
.forEach { println(it) }
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
// WITH_RUNTIME
|
||||
// INTENTION_TEXT: "Replace with 'filter{}.forEach{}'"
|
||||
// INTENTION_TEXT_2: "Replace with 'asSequence().filter{}.forEach{}'"
|
||||
fun foo(list: List<String?>){
|
||||
list
|
||||
.asSequence()
|
||||
.filter { it != null && it.startsWith("IMG:") }
|
||||
.forEach { println(it) }
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
// WITH_RUNTIME
|
||||
// INTENTION_TEXT: "Replace with 'filterIsInstance<>().filterTo(){}'"
|
||||
// INTENTION_TEXT_2: "Replace with 'asSequence().filterIsInstance<>().filterTo(){}'"
|
||||
fun foo(list: List<Any>, out: MutableList<String>){
|
||||
<caret>for (any in list) {
|
||||
if (any is String && any.length > 0)
|
||||
out.add(any)
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
// WITH_RUNTIME
|
||||
// INTENTION_TEXT: "Replace with 'filterIsInstance<>().filterTo(){}'"
|
||||
// INTENTION_TEXT_2: "Replace with 'asSequence().filterIsInstance<>().filterTo(){}'"
|
||||
fun foo(list: List<Any>, out: MutableList<String>){
|
||||
list
|
||||
.filterIsInstance<String>()
|
||||
.filterTo(out) { it.length > 0 }
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
// WITH_RUNTIME
|
||||
// INTENTION_TEXT: "Replace with 'filterIsInstance<>().filterTo(){}'"
|
||||
// INTENTION_TEXT_2: "Replace with 'asSequence().filterIsInstance<>().filterTo(){}'"
|
||||
fun foo(list: List<Any>, out: MutableList<String>){
|
||||
list
|
||||
.asSequence()
|
||||
.filterIsInstance<String>()
|
||||
.filterTo(out) { it.length > 0 }
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
// WITH_RUNTIME
|
||||
// INTENTION_TEXT: "Replace with 'filterNotNull().filter{}.forEach{}'"
|
||||
// INTENTION_TEXT_2: "Replace with 'asSequence().filterNotNull().filter{}.forEach{}'"
|
||||
fun foo(list: List<String?>){
|
||||
<caret>for (l in list) {
|
||||
if (l != null && l.startsWith("IMG:"))
|
||||
println(l.hashCode())
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
// WITH_RUNTIME
|
||||
// INTENTION_TEXT: "Replace with 'filterNotNull().filter{}.forEach{}'"
|
||||
// INTENTION_TEXT_2: "Replace with 'asSequence().filterNotNull().filter{}.forEach{}'"
|
||||
fun foo(list: List<String?>){
|
||||
list
|
||||
.filterNotNull()
|
||||
.filter { it.startsWith("IMG:") }
|
||||
.forEach { println(it.hashCode()) }
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
// WITH_RUNTIME
|
||||
// INTENTION_TEXT: "Replace with 'filterNotNull().filter{}.forEach{}'"
|
||||
// INTENTION_TEXT_2: "Replace with 'asSequence().filterNotNull().filter{}.forEach{}'"
|
||||
fun foo(list: List<String?>){
|
||||
list
|
||||
.asSequence()
|
||||
.filterNotNull()
|
||||
.filter { it.startsWith("IMG:") }
|
||||
.forEach { println(it.hashCode()) }
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
// WITH_RUNTIME
|
||||
// INTENTION_TEXT: "Replace with 'filterNotNull().filter{}.forEach{}'"
|
||||
// INTENTION_TEXT_2: "Replace with 'asSequence().filterNotNull().filter{}.forEach{}'"
|
||||
fun foo(list: List<String?>){
|
||||
<caret>for (l in list) {
|
||||
if (l == null || !l.startsWith("IMG:")) continue
|
||||
println(l.hashCode())
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
// WITH_RUNTIME
|
||||
// INTENTION_TEXT: "Replace with 'filterNotNull().filter{}.forEach{}'"
|
||||
// INTENTION_TEXT_2: "Replace with 'asSequence().filterNotNull().filter{}.forEach{}'"
|
||||
fun foo(list: List<String?>){
|
||||
list
|
||||
.filterNotNull()
|
||||
.filter { it.startsWith("IMG:") }
|
||||
.forEach { println(it.hashCode()) }
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
// WITH_RUNTIME
|
||||
// INTENTION_TEXT: "Replace with 'filterNotNull().filter{}.forEach{}'"
|
||||
// INTENTION_TEXT_2: "Replace with 'asSequence().filterNotNull().filter{}.forEach{}'"
|
||||
fun foo(list: List<String?>){
|
||||
list
|
||||
.asSequence()
|
||||
.filterNotNull()
|
||||
.filter { it.startsWith("IMG:") }
|
||||
.forEach { println(it.hashCode()) }
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
// WITH_RUNTIME
|
||||
// INTENTION_TEXT: "Replace with 'filterNotNull().firstOrNull{}'"
|
||||
// INTENTION_TEXT_2: "Replace with 'asSequence().filterNotNull().firstOrNull{}'"
|
||||
// INTENTION_TEXT: "Replace with 'firstOrNull{}'"
|
||||
// IS_APPLICABLE_2: false
|
||||
|
||||
fun getFirstValue() = "value"
|
||||
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
// WITH_RUNTIME
|
||||
// INTENTION_TEXT: "Replace with 'filterNotNull().firstOrNull{}'"
|
||||
// INTENTION_TEXT_2: "Replace with 'asSequence().filterNotNull().firstOrNull{}'"
|
||||
// INTENTION_TEXT: "Replace with 'firstOrNull{}'"
|
||||
// IS_APPLICABLE_2: false
|
||||
|
||||
fun getFirstValue() = "value"
|
||||
|
||||
fun foo(list: List<String?>): String? {
|
||||
val value = getFirstValue()
|
||||
val <caret>found: String? = list
|
||||
.filterNotNull()
|
||||
.firstOrNull { !it.startsWith("IMG:") && it.contains(value) }
|
||||
val found: String? = list.firstOrNull { it != null && !it.startsWith("IMG:") && it.contains(value) }
|
||||
return found
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
// WITH_RUNTIME
|
||||
// INTENTION_TEXT: "Replace with 'filterNotNull().firstOrNull{}'"
|
||||
// INTENTION_TEXT_2: "Replace with 'asSequence().filterNotNull().firstOrNull{}'"
|
||||
|
||||
fun getFirstValue() = "value"
|
||||
|
||||
fun foo(list: List<String?>): String? {
|
||||
val value = getFirstValue()
|
||||
val <caret>found: String? = list
|
||||
.asSequence()
|
||||
.filterNotNull()
|
||||
.firstOrNull { !it.startsWith("IMG:") && it.contains(value) }
|
||||
return found
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
// WITH_RUNTIME
|
||||
// INTENTION_TEXT: "Replace with 'indexOfFirst{}'"
|
||||
// IS_APPLICABLE_2: false
|
||||
fun f8_indexOfFirst_complex(value: String, list: List<Any?>):Int{
|
||||
<caret>for ((i, any) in list.withIndex())
|
||||
if (any != null)
|
||||
if (any is String)
|
||||
if (any == value)
|
||||
return i
|
||||
return -1
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// WITH_RUNTIME
|
||||
// INTENTION_TEXT: "Replace with 'indexOfFirst{}'"
|
||||
// IS_APPLICABLE_2: false
|
||||
fun f8_indexOfFirst_complex(value: String, list: List<Any?>):Int{
|
||||
return list.indexOfFirst { it != null && it is String && it == value }
|
||||
}
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
// WITH_RUNTIME
|
||||
// INTENTION_TEXT: "Replace with 'flatMap{}.filterNot{}.mapIndexedTo(){}'"
|
||||
// INTENTION_TEXT_2: "Replace with 'asSequence().flatMap{}.filterNot{}.mapIndexedTo(){}'"
|
||||
// INTENTION_TEXT: "Replace with 'flatMap{}.filter{}.mapIndexedTo(){}'"
|
||||
// INTENTION_TEXT_2: "Replace with 'asSequence().flatMap{}.filter{}.mapIndexedTo(){}'"
|
||||
fun foo(list: List<String>, target: MutableCollection<Int>) {
|
||||
var i = 0
|
||||
<caret>for (s in list) {
|
||||
|
||||
+3
-3
@@ -1,9 +1,9 @@
|
||||
// WITH_RUNTIME
|
||||
// INTENTION_TEXT: "Replace with 'flatMap{}.filterNot{}.mapIndexedTo(){}'"
|
||||
// INTENTION_TEXT_2: "Replace with 'asSequence().flatMap{}.filterNot{}.mapIndexedTo(){}'"
|
||||
// INTENTION_TEXT: "Replace with 'flatMap{}.filter{}.mapIndexedTo(){}'"
|
||||
// INTENTION_TEXT_2: "Replace with 'asSequence().flatMap{}.filter{}.mapIndexedTo(){}'"
|
||||
fun foo(list: List<String>, target: MutableCollection<Int>) {
|
||||
<caret>list
|
||||
.flatMap { it.indices }
|
||||
.filterNot { it == 10 }
|
||||
.filter { it != 10 }
|
||||
.mapIndexedTo(target) { i, j -> i + j }
|
||||
}
|
||||
+3
-3
@@ -1,10 +1,10 @@
|
||||
// WITH_RUNTIME
|
||||
// INTENTION_TEXT: "Replace with 'flatMap{}.filterNot{}.mapIndexedTo(){}'"
|
||||
// INTENTION_TEXT_2: "Replace with 'asSequence().flatMap{}.filterNot{}.mapIndexedTo(){}'"
|
||||
// INTENTION_TEXT: "Replace with 'flatMap{}.filter{}.mapIndexedTo(){}'"
|
||||
// INTENTION_TEXT_2: "Replace with 'asSequence().flatMap{}.filter{}.mapIndexedTo(){}'"
|
||||
fun foo(list: List<String>, target: MutableCollection<Int>) {
|
||||
<caret>list
|
||||
.asSequence()
|
||||
.flatMap { it.indices.asSequence() }
|
||||
.filterNot { it == 10 }
|
||||
.filter { it != 10 }
|
||||
.mapIndexedTo(target) { i, j -> i + j }
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
// WITH_RUNTIME
|
||||
// IS_APPLICABLE: false
|
||||
// IS_APPLICABLE_2: false
|
||||
// INTENTION_TEXT: "Replace with '...filter{}.map{}.firstOrNull()'"
|
||||
// INTENTION_TEXT_2: "Replace with 'asSequence()...filter{}.map{}.firstOrNull()'"
|
||||
fun foo(list: List<Any>, o: Any): Int? {
|
||||
<caret>for (s in list) {
|
||||
if (s is String && s.length > 0) {
|
||||
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
// WITH_RUNTIME
|
||||
// INTENTION_TEXT: "Replace with '...filter{}.map{}.firstOrNull()'"
|
||||
// INTENTION_TEXT_2: "Replace with 'asSequence()...filter{}.map{}.firstOrNull()'"
|
||||
fun foo(list: List<Any>, o: Any): Int? {
|
||||
return list
|
||||
.filterIsInstance<String>()
|
||||
.filter { it.length > 0 }
|
||||
.map { it.length * 2 }
|
||||
.firstOrNull()
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
// WITH_RUNTIME
|
||||
// INTENTION_TEXT: "Replace with '...filter{}.map{}.firstOrNull()'"
|
||||
// INTENTION_TEXT_2: "Replace with 'asSequence()...filter{}.map{}.firstOrNull()'"
|
||||
fun foo(list: List<Any>, o: Any): Int? {
|
||||
return list
|
||||
.asSequence()
|
||||
.filterIsInstance<String>()
|
||||
.filter { it.length > 0 }
|
||||
.map { it.length * 2 }
|
||||
.firstOrNull()
|
||||
}
|
||||
@@ -358,6 +358,18 @@ public class IntentionTest2Generated extends AbstractIntentionTest2 {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("doNotSplitOutFilterIsInstance.kt")
|
||||
public void testDoNotSplitOutFilterIsInstance() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/loopToCallChain/filter/doNotSplitOutFilterIsInstance.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("doNotSplitOutFilterNotNull.kt")
|
||||
public void testDoNotSplitOutFilterNotNull() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/loopToCallChain/filter/doNotSplitOutFilterNotNull.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("filterIndexed.kt")
|
||||
public void testFilterIndexed() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/loopToCallChain/filter/filterIndexed.kt");
|
||||
@@ -514,6 +526,12 @@ public class IntentionTest2Generated extends AbstractIntentionTest2 {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("glueTogetherFilterNotNull.kt")
|
||||
public void testGlueTogetherFilterNotNull() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/loopToCallChain/filter/glueTogetherFilterNotNull.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("ifContinue.kt")
|
||||
public void testIfContinue() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/loopToCallChain/filter/ifContinue.kt");
|
||||
@@ -555,6 +573,24 @@ public class IntentionTest2Generated extends AbstractIntentionTest2 {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/loopToCallChain/filter/mergeMultiple.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("splitOutFilterIsInstance.kt")
|
||||
public void testSplitOutFilterIsInstance() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/loopToCallChain/filter/splitOutFilterIsInstance.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("splitOutFilterNotNull.kt")
|
||||
public void testSplitOutFilterNotNull() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/loopToCallChain/filter/splitOutFilterNotNull.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("splitOutFilterNotNull2.kt")
|
||||
public void testSplitOutFilterNotNull2() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/loopToCallChain/filter/splitOutFilterNotNull2.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/intentions/loopToCallChain/firstOrNull")
|
||||
@@ -844,6 +880,12 @@ public class IntentionTest2Generated extends AbstractIntentionTest2 {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("KT14303.kt")
|
||||
public void testKT14303() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/loopToCallChain/indexOf/KT14303.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("lastIndexOf.kt")
|
||||
public void testLastIndexOf() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/loopToCallChain/indexOf/lastIndexOf.kt");
|
||||
|
||||
@@ -8266,6 +8266,18 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("doNotSplitOutFilterIsInstance.kt")
|
||||
public void testDoNotSplitOutFilterIsInstance() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/loopToCallChain/filter/doNotSplitOutFilterIsInstance.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("doNotSplitOutFilterNotNull.kt")
|
||||
public void testDoNotSplitOutFilterNotNull() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/loopToCallChain/filter/doNotSplitOutFilterNotNull.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("filterIndexed.kt")
|
||||
public void testFilterIndexed() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/loopToCallChain/filter/filterIndexed.kt");
|
||||
@@ -8422,6 +8434,12 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("glueTogetherFilterNotNull.kt")
|
||||
public void testGlueTogetherFilterNotNull() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/loopToCallChain/filter/glueTogetherFilterNotNull.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("ifContinue.kt")
|
||||
public void testIfContinue() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/loopToCallChain/filter/ifContinue.kt");
|
||||
@@ -8463,6 +8481,24 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/loopToCallChain/filter/mergeMultiple.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("splitOutFilterIsInstance.kt")
|
||||
public void testSplitOutFilterIsInstance() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/loopToCallChain/filter/splitOutFilterIsInstance.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("splitOutFilterNotNull.kt")
|
||||
public void testSplitOutFilterNotNull() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/loopToCallChain/filter/splitOutFilterNotNull.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("splitOutFilterNotNull2.kt")
|
||||
public void testSplitOutFilterNotNull2() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/loopToCallChain/filter/splitOutFilterNotNull2.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/intentions/loopToCallChain/firstOrNull")
|
||||
@@ -8752,6 +8788,12 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("KT14303.kt")
|
||||
public void testKT14303() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/loopToCallChain/indexOf/KT14303.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("lastIndexOf.kt")
|
||||
public void testLastIndexOf() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/loopToCallChain/indexOf/lastIndexOf.kt");
|
||||
|
||||
Reference in New Issue
Block a user