Add "Replace 'associate' with 'associateBy' or 'associateWith'" inspection

#KT-26269 Fixed
This commit is contained in:
Toshiaki Kameyama
2019-01-29 19:14:44 +09:00
committed by Mikhail Glukhikh
parent 42120b93b8
commit f1e66d0654
68 changed files with 1064 additions and 0 deletions
@@ -3313,6 +3313,15 @@
language="kotlin"
/>
<localInspection implementationClass="org.jetbrains.kotlin.idea.inspections.ReplaceAssociateFunctionInspection"
displayName="Replace 'associate' with 'associateBy' or 'associateWith'"
groupPath="Kotlin"
groupName="Style issues"
enabledByDefault="true"
level="WEAK WARNING"
language="kotlin"
/>
<referenceImporter implementation="org.jetbrains.kotlin.idea.quickfix.KotlinReferenceImporter"/>
<fileType.fileViewProviderFactory filetype="KJSM" implementationClass="com.intellij.psi.ClassFileViewProviderFactory"/>
@@ -0,0 +1,5 @@
<html>
<body>
This inspection reports <b>associate</b> calls that can be replaced with <b>associateBy</b> or <b>associateWith</b>.
</body>
</html>
@@ -0,0 +1,194 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.idea.inspections
import com.intellij.codeInspection.LocalQuickFix
import com.intellij.codeInspection.ProblemDescriptor
import com.intellij.codeInspection.ProblemHighlightType.GENERIC_ERROR_OR_WARNING
import com.intellij.codeInspection.ProblemHighlightType.INFORMATION
import com.intellij.codeInspection.ProblemsHolder
import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.config.LanguageVersion
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.core.getLastLambdaExpression
import org.jetbrains.kotlin.idea.inspections.AssociateFunction.*
import org.jetbrains.kotlin.idea.intentions.callExpression
import org.jetbrains.kotlin.idea.project.languageVersionSettings
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.anyDescendantOfType
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
class ReplaceAssociateFunctionInspection : AbstractKotlinInspection() {
companion object {
private val associateFunctionNames = listOf("associate", "associateTo")
private val associateFqNames = listOf(FqName("kotlin.collections.associate"), FqName("kotlin.sequences.associate"))
private val associateToFqNames = listOf(FqName("kotlin.collections.associateTo"), FqName("kotlin.sequences.associateTo"))
}
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean) = dotQualifiedExpressionVisitor(fun(dotQualifiedExpression) {
if (dotQualifiedExpression.languageVersionSettings.languageVersion < LanguageVersion.KOTLIN_1_3) return
val callExpression = dotQualifiedExpression.callExpression ?: return
val calleeExpression = callExpression.calleeExpression ?: return
if (calleeExpression.text !in associateFunctionNames) return
val context = dotQualifiedExpression.analyze(BodyResolveMode.PARTIAL)
val fqName = callExpression.getResolvedCall(context)?.resultingDescriptor?.fqNameSafe ?: return
val isAssociate = fqName in associateFqNames
val isAssociateTo = fqName in associateToFqNames
if (!isAssociate && !isAssociateTo) return
val lambda = callExpression.lambda() ?: return
if (lambda.valueParameters.size > 1) return
val functionLiteral = lambda.functionLiteral
if (functionLiteral.anyDescendantOfType<KtReturnExpression> { it.labelQualifier != null }) return
val lastStatement = functionLiteral.lastStatement() ?: return
val (keySelector, valueTransform) = lastStatement.pair(context) ?: return
val lambdaParameter = context[BindingContext.FUNCTION, functionLiteral]?.valueParameters?.singleOrNull() ?: return
val (associateFunction, highlightType) = when {
keySelector.isReferenceTo(lambdaParameter, context) -> {
val receiver = dotQualifiedExpression.receiverExpression.getResolvedCall(context)?.resultingDescriptor?.returnType ?: return
if (KotlinBuiltIns.isArray(receiver) || KotlinBuiltIns.isPrimitiveArray(receiver)) return
ASSOCIATE_WITH to GENERIC_ERROR_OR_WARNING
}
valueTransform.isReferenceTo(lambdaParameter, context) ->
ASSOCIATE_BY to GENERIC_ERROR_OR_WARNING
else -> {
if (functionLiteral.bodyExpression?.statements?.size != 1) return
ASSOCIATE_BY_KEY_AND_VALUE to INFORMATION
}
}
holder.registerProblemWithoutOfflineInformation(
calleeExpression,
"Replace '${calleeExpression.text}' with '${associateFunction.name(isAssociateTo)}'",
isOnTheFly,
highlightType,
ReplaceAssociateFunctionFix(associateFunction, isAssociateTo)
)
})
private fun KtExpression.isReferenceTo(descriptor: ValueParameterDescriptor, context: BindingContext): Boolean {
return (this as? KtNameReferenceExpression)?.getResolvedCall(context)?.resultingDescriptor == descriptor
}
}
private class ReplaceAssociateFunctionFix(private val function: AssociateFunction, private val hasDestination: Boolean) : LocalQuickFix {
private val functionName = function.name(hasDestination)
override fun getName() = "Replace with '$functionName'"
override fun getFamilyName() = name
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
val dotQualifiedExpression = descriptor.psiElement.getStrictParentOfType<KtDotQualifiedExpression>() ?: return
val receiverExpression = dotQualifiedExpression.receiverExpression
val callExpression = dotQualifiedExpression.callExpression ?: return
val lambda = callExpression.lambda() ?: return
val lastStatement = lambda.functionLiteral.lastStatement() ?: return
val (keySelector, valueTransform) = lastStatement.pair() ?: return
val psiFactory = KtPsiFactory(dotQualifiedExpression)
if (function == ASSOCIATE_BY_KEY_AND_VALUE) {
val destination = if (hasDestination) {
callExpression.valueArguments.firstOrNull()?.getArgumentExpression() ?: return
} else {
null
}
val newExpression = psiFactory.buildExpression {
appendExpression(receiverExpression)
appendFixedText(".")
appendFixedText(functionName)
appendFixedText("(")
if (destination != null) {
appendExpression(destination)
appendFixedText(",")
}
appendLambda(lambda, keySelector)
appendFixedText(",")
appendLambda(lambda, valueTransform)
appendFixedText(")")
}
dotQualifiedExpression.replace(newExpression)
} else {
lastStatement.replace(if (function == ASSOCIATE_WITH) valueTransform else keySelector)
val newExpression = psiFactory.buildExpression {
appendExpression(receiverExpression)
appendFixedText(".")
appendFixedText(functionName)
val valueArgumentList = callExpression.valueArgumentList
if (valueArgumentList != null) {
appendValueArgumentList(valueArgumentList)
}
if (callExpression.lambdaArguments.isNotEmpty()) {
appendLambda(lambda)
}
}
dotQualifiedExpression.replace(newExpression)
}
}
private fun BuilderByPattern<KtExpression>.appendLambda(lambda: KtLambdaExpression, body: KtExpression? = lambda.bodyExpression) {
appendFixedText("{")
lambda.valueParameters.firstOrNull()?.nameAsName?.also {
appendName(it)
appendFixedText("->")
}
appendExpression(body)
appendFixedText("}")
}
private fun BuilderByPattern<KtExpression>.appendValueArgumentList(valueArgumentList: KtValueArgumentList) {
appendFixedText("(")
valueArgumentList.arguments.forEachIndexed { index, argument ->
if (index > 0) appendFixedText(",")
appendExpression(argument.getArgumentExpression())
}
appendFixedText(")")
}
}
private enum class AssociateFunction(private val functionName: String) {
ASSOCIATE_WITH("associateWith"), ASSOCIATE_BY("associateBy"), ASSOCIATE_BY_KEY_AND_VALUE("associateBy");
fun name(hasDestination: Boolean): String {
return if (hasDestination) "${functionName}To" else functionName
}
}
private fun KtCallExpression.lambda(): KtLambdaExpression? {
return lambdaArguments.singleOrNull()?.getArgumentExpression() as? KtLambdaExpression ?: getLastLambdaExpression()
}
private fun KtFunctionLiteral.lastStatement(): KtExpression? {
return bodyExpression?.statements?.lastOrNull()
}
private fun KtExpression.pair(context: BindingContext = analyze(BodyResolveMode.PARTIAL)): Pair<KtExpression, KtExpression>? {
return when (this) {
is KtBinaryExpression -> {
if (operationReference.text != "to") return null
val left = left ?: return null
val right = right ?: return null
left to right
}
is KtCallExpression -> {
if (calleeExpression?.text != "Pair") return null
if (valueArguments.size != 2) return null
if (getResolvedCall(context)?.resultingDescriptor?.containingDeclaration?.fqNameSafe != FqName("kotlin.Pair")) return null
val first = valueArguments[0]?.getArgumentExpression() ?: return null
val second = valueArguments[1]?.getArgumentExpression() ?: return null
first to second
}
else -> return null
}
}
@@ -0,0 +1 @@
org.jetbrains.kotlin.idea.inspections.ReplaceAssociateFunctionInspection
@@ -0,0 +1,8 @@
// PROBLEM: Replace 'associate' with 'associateBy'
// FIX: Replace with 'associateBy'
// WITH_RUNTIME
fun getKey(i: Int): Long = 1L
fun test() {
arrayOf(1).<caret>associate { getKey(it) to it }
}
@@ -0,0 +1,8 @@
// PROBLEM: Replace 'associate' with 'associateBy'
// FIX: Replace with 'associateBy'
// WITH_RUNTIME
fun getKey(i: Int): Long = 1L
fun test() {
arrayOf(1).associateBy { getKey(it) }
}
@@ -0,0 +1,8 @@
// PROBLEM: Replace 'associate' with 'associateBy'
// FIX: Replace with 'associateBy'
// WITH_RUNTIME
fun getKey(i: Int): Long = 1L
fun test() {
listOf(1).<caret>associate { getKey(it) to it }
}
@@ -0,0 +1,8 @@
// PROBLEM: Replace 'associate' with 'associateBy'
// FIX: Replace with 'associateBy'
// WITH_RUNTIME
fun getKey(i: Int): Long = 1L
fun test() {
listOf(1).associateBy { getKey(it) }
}
@@ -0,0 +1,10 @@
// HIGHLIGHT: INFORMATION
// PROBLEM: Replace 'associate' with 'associateBy'
// FIX: Replace with 'associateBy'
// WITH_RUNTIME
fun getKey(i: Int): Long = 1L
fun getValue(i: Int): String = ""
fun test() {
arrayOf(1).<caret>associate { getKey(it) to getValue(it) }
}
@@ -0,0 +1,10 @@
// HIGHLIGHT: INFORMATION
// PROBLEM: Replace 'associate' with 'associateBy'
// FIX: Replace with 'associateBy'
// WITH_RUNTIME
fun getKey(i: Int): Long = 1L
fun getValue(i: Int): String = ""
fun test() {
arrayOf(1).associateBy({ getKey(it) }, { getValue(it) })
}
@@ -0,0 +1,10 @@
// HIGHLIGHT: INFORMATION
// PROBLEM: Replace 'associate' with 'associateBy'
// FIX: Replace with 'associateBy'
// WITH_RUNTIME
fun getKey(i: Int): Long = 1L
fun getValue(i: Int): String = ""
fun test() {
listOf(1).<caret>associate { getKey(it) to getValue(it) }
}
@@ -0,0 +1,10 @@
// HIGHLIGHT: INFORMATION
// PROBLEM: Replace 'associate' with 'associateBy'
// FIX: Replace with 'associateBy'
// WITH_RUNTIME
fun getKey(i: Int): Long = 1L
fun getValue(i: Int): String = ""
fun test() {
listOf(1).associateBy({ getKey(it) }, { getValue(it) })
}
@@ -0,0 +1,10 @@
// HIGHLIGHT: INFORMATION
// PROBLEM: Replace 'associate' with 'associateBy'
// FIX: Replace with 'associateBy'
// WITH_RUNTIME
fun getKey(i: Int): Long = 1L
fun getValue(i: Int): String = ""
fun test() {
listOf(1).<caret>associate { i -> getKey(i) to getValue(i) }
}
@@ -0,0 +1,10 @@
// HIGHLIGHT: INFORMATION
// PROBLEM: Replace 'associate' with 'associateBy'
// FIX: Replace with 'associateBy'
// WITH_RUNTIME
fun getKey(i: Int): Long = 1L
fun getValue(i: Int): String = ""
fun test() {
listOf(1).associateBy({ i -> getKey(i) }, { i -> getValue(i) })
}
@@ -0,0 +1,10 @@
// HIGHLIGHT: INFORMATION
// PROBLEM: Replace 'associate' with 'associateBy'
// FIX: Replace with 'associateBy'
// WITH_RUNTIME
fun getKey(i: Int): Long = 1L
fun getValue(i: Int): String = ""
fun test() {
listOf(1).<caret>associate { Pair(getKey(it), getValue(it)) }
}
@@ -0,0 +1,10 @@
// HIGHLIGHT: INFORMATION
// PROBLEM: Replace 'associate' with 'associateBy'
// FIX: Replace with 'associateBy'
// WITH_RUNTIME
fun getKey(i: Int): Long = 1L
fun getValue(i: Int): String = ""
fun test() {
listOf(1).associateBy({ getKey(it) }, { getValue(it) })
}
@@ -0,0 +1,10 @@
// HIGHLIGHT: INFORMATION
// PROBLEM: Replace 'associate' with 'associateBy'
// FIX: Replace with 'associateBy'
// WITH_RUNTIME
fun getKey(i: Int): Long = 1L
fun getValue(i: Int): String = ""
fun test() {
listOf(1).<caret>associate({ getKey(it) to getValue(it) })
}
@@ -0,0 +1,10 @@
// HIGHLIGHT: INFORMATION
// PROBLEM: Replace 'associate' with 'associateBy'
// FIX: Replace with 'associateBy'
// WITH_RUNTIME
fun getKey(i: Int): Long = 1L
fun getValue(i: Int): String = ""
fun test() {
listOf(1).associateBy({ getKey(it) }, { getValue(it) })
}
@@ -0,0 +1,10 @@
// HIGHLIGHT: INFORMATION
// PROBLEM: Replace 'associate' with 'associateBy'
// FIX: Replace with 'associateBy'
// WITH_RUNTIME
fun getKey(i: Int): Long = 1L
fun getValue(i: Int): String = ""
fun test() {
listOf(1).<caret>associate { "$it" to "$it" }
}
@@ -0,0 +1,10 @@
// HIGHLIGHT: INFORMATION
// PROBLEM: Replace 'associate' with 'associateBy'
// FIX: Replace with 'associateBy'
// WITH_RUNTIME
fun getKey(i: Int): Long = 1L
fun getValue(i: Int): String = ""
fun test() {
listOf(1).associateBy({ "$it" }, { "$it" })
}
@@ -0,0 +1,12 @@
// PROBLEM: none
// WITH_RUNTIME
fun getKey(i: Int): Long = 1L
fun getValue(i: Int): String = ""
fun test() {
listOf(1).<caret>associate {
val key = getKey(it)
val value = getValue(it)
key to value
}
}
@@ -0,0 +1,9 @@
// PROBLEM: Replace 'associateTo' with 'associateByTo'
// FIX: Replace with 'associateByTo'
// WITH_RUNTIME
fun getKey(i: Int): Long = 1L
fun test() {
val destination = mutableMapOf<Long, Int>()
arrayOf(1).<caret>associateTo(destination) { getKey(it) to it }
}
@@ -0,0 +1,9 @@
// PROBLEM: Replace 'associateTo' with 'associateByTo'
// FIX: Replace with 'associateByTo'
// WITH_RUNTIME
fun getKey(i: Int): Long = 1L
fun test() {
val destination = mutableMapOf<Long, Int>()
arrayOf(1).associateByTo(destination) { getKey(it) }
}
@@ -0,0 +1,9 @@
// PROBLEM: Replace 'associateTo' with 'associateByTo'
// FIX: Replace with 'associateByTo'
// WITH_RUNTIME
fun getKey(i: Int): Long = 1L
fun test() {
val destination = mutableMapOf<Long, Int>()
listOf(1).<caret>associateTo(destination) { getKey(it) to it }
}
@@ -0,0 +1,9 @@
// PROBLEM: Replace 'associateTo' with 'associateByTo'
// FIX: Replace with 'associateByTo'
// WITH_RUNTIME
fun getKey(i: Int): Long = 1L
fun test() {
val destination = mutableMapOf<Long, Int>()
listOf(1).associateByTo(destination) { getKey(it) }
}
@@ -0,0 +1,11 @@
// HIGHLIGHT: INFORMATION
// PROBLEM: Replace 'associateTo' with 'associateByTo'
// FIX: Replace with 'associateByTo'
// WITH_RUNTIME
fun getKey(i: Int): Long = 1L
fun getValue(i: Int): String = ""
fun test() {
val destination = mutableMapOf<Long, String>()
arrayOf(1).<caret>associateTo(destination) { getKey(it) to getValue(it) }
}
@@ -0,0 +1,11 @@
// HIGHLIGHT: INFORMATION
// PROBLEM: Replace 'associateTo' with 'associateByTo'
// FIX: Replace with 'associateByTo'
// WITH_RUNTIME
fun getKey(i: Int): Long = 1L
fun getValue(i: Int): String = ""
fun test() {
val destination = mutableMapOf<Long, String>()
arrayOf(1).associateByTo(destination, { getKey(it) }, { getValue(it) })
}
@@ -0,0 +1,11 @@
// HIGHLIGHT: INFORMATION
// PROBLEM: Replace 'associateTo' with 'associateByTo'
// FIX: Replace with 'associateByTo'
// WITH_RUNTIME
fun getKey(i: Int): Long = 1L
fun getValue(i: Int): String = ""
fun test() {
val destination = mutableMapOf<Long, String>()
listOf(1).<caret>associateTo(destination) { getKey(it) to getValue(it) }
}
@@ -0,0 +1,11 @@
// HIGHLIGHT: INFORMATION
// PROBLEM: Replace 'associateTo' with 'associateByTo'
// FIX: Replace with 'associateByTo'
// WITH_RUNTIME
fun getKey(i: Int): Long = 1L
fun getValue(i: Int): String = ""
fun test() {
val destination = mutableMapOf<Long, String>()
listOf(1).associateByTo(destination, { getKey(it) }, { getValue(it) })
}
@@ -0,0 +1,11 @@
// HIGHLIGHT: INFORMATION
// PROBLEM: Replace 'associateTo' with 'associateByTo'
// FIX: Replace with 'associateByTo'
// WITH_RUNTIME
fun getKey(i: Int): Long = 1L
fun getValue(i: Int): String = ""
fun test() {
val destination = mutableMapOf<Long, String>()
listOf(1).<caret>associateTo(destination) { i -> getKey(i) to getValue(i) }
}
@@ -0,0 +1,11 @@
// HIGHLIGHT: INFORMATION
// PROBLEM: Replace 'associateTo' with 'associateByTo'
// FIX: Replace with 'associateByTo'
// WITH_RUNTIME
fun getKey(i: Int): Long = 1L
fun getValue(i: Int): String = ""
fun test() {
val destination = mutableMapOf<Long, String>()
listOf(1).associateByTo(destination, { i -> getKey(i) }, { i -> getValue(i) })
}
@@ -0,0 +1,11 @@
// HIGHLIGHT: INFORMATION
// PROBLEM: Replace 'associateTo' with 'associateByTo'
// FIX: Replace with 'associateByTo'
// WITH_RUNTIME
fun getKey(i: Int): Long = 1L
fun getValue(i: Int): String = ""
fun test() {
val destination = mutableMapOf<Long, String>()
listOf(1).<caret>associateTo(destination) { Pair(getKey(it), getValue(it)) }
}
@@ -0,0 +1,11 @@
// HIGHLIGHT: INFORMATION
// PROBLEM: Replace 'associateTo' with 'associateByTo'
// FIX: Replace with 'associateByTo'
// WITH_RUNTIME
fun getKey(i: Int): Long = 1L
fun getValue(i: Int): String = ""
fun test() {
val destination = mutableMapOf<Long, String>()
listOf(1).associateByTo(destination, { getKey(it) }, { getValue(it) })
}
@@ -0,0 +1,11 @@
// HIGHLIGHT: INFORMATION
// PROBLEM: Replace 'associateTo' with 'associateByTo'
// FIX: Replace with 'associateByTo'
// WITH_RUNTIME
fun getKey(i: Int): Long = 1L
fun getValue(i: Int): String = ""
fun test() {
val destination = mutableMapOf<Long, String>()
listOf(1).<caret>associateTo(destination, { getKey(it) to getValue(it) })
}
@@ -0,0 +1,11 @@
// HIGHLIGHT: INFORMATION
// PROBLEM: Replace 'associateTo' with 'associateByTo'
// FIX: Replace with 'associateByTo'
// WITH_RUNTIME
fun getKey(i: Int): Long = 1L
fun getValue(i: Int): String = ""
fun test() {
val destination = mutableMapOf<Long, String>()
listOf(1).associateByTo(destination, { getKey(it) }, { getValue(it) })
}
@@ -0,0 +1,7 @@
// PROBLEM: none
// WITH_RUNTIME
fun getValue(i: Int): String = ""
fun test() {
arrayOf(1).<caret>associate { it to getValue(it) }
}
@@ -0,0 +1,8 @@
// PROBLEM: Replace 'associate' with 'associateWith'
// FIX: Replace with 'associateWith'
// WITH_RUNTIME
fun getValue(i: Int): String = ""
fun test() {
listOf(1).<caret>associate { it to getValue(it) }
}
@@ -0,0 +1,8 @@
// PROBLEM: Replace 'associate' with 'associateWith'
// FIX: Replace with 'associateWith'
// WITH_RUNTIME
fun getValue(i: Int): String = ""
fun test() {
listOf(1).associateWith { getValue(it) }
}
@@ -0,0 +1,8 @@
// PROBLEM: Replace 'associate' with 'associateWith'
// FIX: Replace with 'associateWith'
// WITH_RUNTIME
fun getValue(i: Int): String = ""
fun test() {
listOf(1).associate<caret> { i -> i to getValue(i) }
}
@@ -0,0 +1,8 @@
// PROBLEM: Replace 'associate' with 'associateWith'
// FIX: Replace with 'associateWith'
// WITH_RUNTIME
fun getValue(i: Int): String = ""
fun test() {
listOf(1).associateWith { i -> getValue(i) }
}
@@ -0,0 +1,8 @@
// PROBLEM: Replace 'associate' with 'associateWith'
// FIX: Replace with 'associateWith'
// WITH_RUNTIME
fun getValue(i: Int): String = ""
fun test() {
listOf(1).<caret>associate { Pair(it, getValue(it)) }
}
@@ -0,0 +1,8 @@
// PROBLEM: Replace 'associate' with 'associateWith'
// FIX: Replace with 'associateWith'
// WITH_RUNTIME
fun getValue(i: Int): String = ""
fun test() {
listOf(1).associateWith { getValue(it) }
}
@@ -0,0 +1,8 @@
// PROBLEM: Replace 'associate' with 'associateWith'
// FIX: Replace with 'associateWith'
// WITH_RUNTIME
fun getValue(i: Int): String = ""
fun test() {
listOf(1).<caret>associate({ it to getValue(it) })
}
@@ -0,0 +1,8 @@
// PROBLEM: Replace 'associate' with 'associateWith'
// FIX: Replace with 'associateWith'
// WITH_RUNTIME
fun getValue(i: Int): String = ""
fun test() {
listOf(1).associateWith({ getValue(it) })
}
@@ -0,0 +1,8 @@
// PROBLEM: Replace 'associate' with 'associateWith'
// FIX: Replace with 'associateWith'
// WITH_RUNTIME
fun getValue(i: Int): String = ""
fun test() {
listOf(1).<caret>associate { it to "$it" }
}
@@ -0,0 +1,8 @@
// PROBLEM: Replace 'associate' with 'associateWith'
// FIX: Replace with 'associateWith'
// WITH_RUNTIME
fun getValue(i: Int): String = ""
fun test() {
listOf(1).associateWith { "$it" }
}
@@ -0,0 +1,7 @@
// PROBLEM: none
// WITH_RUNTIME
fun getValue(i: Int): String = ""
fun test() {
intArrayOf(1).<caret>associate { it to getValue(it) }
}
@@ -0,0 +1,12 @@
// PROBLEM: none
// WITH_RUNTIME
fun getValue(i: Int): String = ""
fun test(b: Boolean) {
listOf(1).<caret>associate {
if (b) {
return@associate it to ""
}
it to getValue(it)
}
}
@@ -0,0 +1,11 @@
// PROBLEM: Replace 'associate' with 'associateWith'
// FIX: Replace with 'associateWith'
// WITH_RUNTIME
fun getValue(i: Int): String = ""
fun test() {
listOf(1).<caret>associate {
val value = getValue(it)
it to value
}
}
@@ -0,0 +1,11 @@
// PROBLEM: Replace 'associate' with 'associateWith'
// FIX: Replace with 'associateWith'
// WITH_RUNTIME
fun getValue(i: Int): String = ""
fun test() {
listOf(1).associateWith {
val value = getValue(it)
value
}
}
@@ -0,0 +1,13 @@
// PROBLEM: none
// WITH_RUNTIME
fun getValue(i: Int): String = ""
fun test(b: Boolean) {
listOf(1).<caret>associate {
if (b) {
it to getValue(it)
} else {
it to ""
}
}
}
@@ -0,0 +1,8 @@
// PROBLEM: Replace 'associate' with 'associateWith'
// FIX: Replace with 'associateWith'
// WITH_RUNTIME
fun getValue(i: Int): String = ""
fun test() {
sequenceOf(1).<caret>associate { it to getValue(it) }
}
@@ -0,0 +1,8 @@
// PROBLEM: Replace 'associate' with 'associateWith'
// FIX: Replace with 'associateWith'
// WITH_RUNTIME
fun getValue(i: Int): String = ""
fun test() {
sequenceOf(1).associateWith { getValue(it) }
}
@@ -0,0 +1,8 @@
// PROBLEM: Replace 'associate' with 'associateWith'
// FIX: Replace with 'associateWith'
// WITH_RUNTIME
fun getValue(i: Int): String = ""
fun test() {
setOf(1).<caret>associate { it to getValue(it) }
}
@@ -0,0 +1,8 @@
// PROBLEM: Replace 'associate' with 'associateWith'
// FIX: Replace with 'associateWith'
// WITH_RUNTIME
fun getValue(i: Int): String = ""
fun test() {
setOf(1).associateWith { getValue(it) }
}
@@ -0,0 +1,8 @@
// PROBLEM: none
// WITH_RUNTIME
fun getValue(i: Int): String = ""
fun associateWithTo() {
val destination = mutableMapOf<Int, String>()
arrayOf(1).<caret>associateTo(destination) { it to getValue(it) }
}
@@ -0,0 +1,9 @@
// PROBLEM: Replace 'associateTo' with 'associateWithTo'
// FIX: Replace with 'associateWithTo'
// WITH_RUNTIME
fun getValue(i: Int): String = ""
fun associateWithTo() {
val destination = mutableMapOf<Int, String>()
listOf(1).<caret>associateTo(destination) { it to getValue(it) }
}
@@ -0,0 +1,9 @@
// PROBLEM: Replace 'associateTo' with 'associateWithTo'
// FIX: Replace with 'associateWithTo'
// WITH_RUNTIME
fun getValue(i: Int): String = ""
fun associateWithTo() {
val destination = mutableMapOf<Int, String>()
listOf(1).associateWithTo(destination) { getValue(it) }
}
@@ -0,0 +1,9 @@
// PROBLEM: Replace 'associateTo' with 'associateWithTo'
// FIX: Replace with 'associateWithTo'
// WITH_RUNTIME
fun getValue(i: Int): String = ""
fun associateWithTo() {
val destination = mutableMapOf<Int, String>()
listOf(1).<caret>associateTo(destination) { i -> i to getValue(i) }
}
@@ -0,0 +1,9 @@
// PROBLEM: Replace 'associateTo' with 'associateWithTo'
// FIX: Replace with 'associateWithTo'
// WITH_RUNTIME
fun getValue(i: Int): String = ""
fun associateWithTo() {
val destination = mutableMapOf<Int, String>()
listOf(1).associateWithTo(destination) { i -> getValue(i) }
}
@@ -0,0 +1,9 @@
// PROBLEM: Replace 'associateTo' with 'associateWithTo'
// FIX: Replace with 'associateWithTo'
// WITH_RUNTIME
fun getValue(i: Int): String = ""
fun associateWithTo() {
val destination = mutableMapOf<Int, String>()
listOf(1).<caret>associateTo(destination) { Pair(it, getValue(it)) }
}
@@ -0,0 +1,9 @@
// PROBLEM: Replace 'associateTo' with 'associateWithTo'
// FIX: Replace with 'associateWithTo'
// WITH_RUNTIME
fun getValue(i: Int): String = ""
fun associateWithTo() {
val destination = mutableMapOf<Int, String>()
listOf(1).associateWithTo(destination) { getValue(it) }
}
@@ -0,0 +1,9 @@
// PROBLEM: Replace 'associateTo' with 'associateWithTo'
// FIX: Replace with 'associateWithTo'
// WITH_RUNTIME
fun getValue(i: Int): String = ""
fun associateWithTo() {
val destination = mutableMapOf<Int, String>()
listOf(1).<caret>associateTo(destination, { it to getValue(it) })
}
@@ -0,0 +1,9 @@
// PROBLEM: Replace 'associateTo' with 'associateWithTo'
// FIX: Replace with 'associateWithTo'
// WITH_RUNTIME
fun getValue(i: Int): String = ""
fun associateWithTo() {
val destination = mutableMapOf<Int, String>()
listOf(1).associateWithTo(destination, { getValue(it) })
}
@@ -0,0 +1,9 @@
// PROBLEM: Replace 'associateTo' with 'associateWithTo'
// FIX: Replace with 'associateWithTo'
// WITH_RUNTIME
fun getValue(i: Int): String = ""
fun associateWithTo() {
val destination = mutableMapOf<Int, String>()
listOf(1).<caret>associateTo(destination, { it to "$it" })
}
@@ -0,0 +1,9 @@
// PROBLEM: Replace 'associateTo' with 'associateWithTo'
// FIX: Replace with 'associateWithTo'
// WITH_RUNTIME
fun getValue(i: Int): String = ""
fun associateWithTo() {
val destination = mutableMapOf<Int, String>()
listOf(1).associateWithTo(destination, { "$it" })
}
@@ -0,0 +1,8 @@
// LANGUAGE_VERSION: 1.2
// PROBLEM: none
// WITH_RUNTIME
fun getValue(i: Int): String = ""
fun test() {
listOf(1).<caret>associate { it to getValue(it) }
}
@@ -6602,6 +6602,272 @@ public class LocalInspectionTestGenerated extends AbstractLocalInspectionTest {
}
}
@TestMetadata("idea/testData/inspectionsLocal/replaceAssociateFunction")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class ReplaceAssociateFunction extends AbstractLocalInspectionTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
}
public void testAllFilesPresentInReplaceAssociateFunction() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/inspectionsLocal/replaceAssociateFunction"), Pattern.compile("^([\\w\\-_]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
}
@TestMetadata("version1_2.kt")
public void testVersion1_2() throws Exception {
runTest("idea/testData/inspectionsLocal/replaceAssociateFunction/version1_2.kt");
}
@TestMetadata("idea/testData/inspectionsLocal/replaceAssociateFunction/associateBy")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class AssociateBy extends AbstractLocalInspectionTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
}
public void testAllFilesPresentInAssociateBy() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/inspectionsLocal/replaceAssociateFunction/associateBy"), Pattern.compile("^([\\w\\-_]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
}
@TestMetadata("array.kt")
public void testArray() throws Exception {
runTest("idea/testData/inspectionsLocal/replaceAssociateFunction/associateBy/array.kt");
}
@TestMetadata("basic.kt")
public void testBasic() throws Exception {
runTest("idea/testData/inspectionsLocal/replaceAssociateFunction/associateBy/basic.kt");
}
}
@TestMetadata("idea/testData/inspectionsLocal/replaceAssociateFunction/associateByKeyAndValue")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class AssociateByKeyAndValue extends AbstractLocalInspectionTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
}
public void testAllFilesPresentInAssociateByKeyAndValue() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/inspectionsLocal/replaceAssociateFunction/associateByKeyAndValue"), Pattern.compile("^([\\w\\-_]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
}
@TestMetadata("array.kt")
public void testArray() throws Exception {
runTest("idea/testData/inspectionsLocal/replaceAssociateFunction/associateByKeyAndValue/array.kt");
}
@TestMetadata("basic.kt")
public void testBasic() throws Exception {
runTest("idea/testData/inspectionsLocal/replaceAssociateFunction/associateByKeyAndValue/basic.kt");
}
@TestMetadata("basic2.kt")
public void testBasic2() throws Exception {
runTest("idea/testData/inspectionsLocal/replaceAssociateFunction/associateByKeyAndValue/basic2.kt");
}
@TestMetadata("basic3.kt")
public void testBasic3() throws Exception {
runTest("idea/testData/inspectionsLocal/replaceAssociateFunction/associateByKeyAndValue/basic3.kt");
}
@TestMetadata("basic4.kt")
public void testBasic4() throws Exception {
runTest("idea/testData/inspectionsLocal/replaceAssociateFunction/associateByKeyAndValue/basic4.kt");
}
@TestMetadata("basic5.kt")
public void testBasic5() throws Exception {
runTest("idea/testData/inspectionsLocal/replaceAssociateFunction/associateByKeyAndValue/basic5.kt");
}
@TestMetadata("notSingle.kt")
public void testNotSingle() throws Exception {
runTest("idea/testData/inspectionsLocal/replaceAssociateFunction/associateByKeyAndValue/notSingle.kt");
}
}
@TestMetadata("idea/testData/inspectionsLocal/replaceAssociateFunction/associateByTo")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class AssociateByTo extends AbstractLocalInspectionTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
}
public void testAllFilesPresentInAssociateByTo() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/inspectionsLocal/replaceAssociateFunction/associateByTo"), Pattern.compile("^([\\w\\-_]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
}
@TestMetadata("array.kt")
public void testArray() throws Exception {
runTest("idea/testData/inspectionsLocal/replaceAssociateFunction/associateByTo/array.kt");
}
@TestMetadata("basic.kt")
public void testBasic() throws Exception {
runTest("idea/testData/inspectionsLocal/replaceAssociateFunction/associateByTo/basic.kt");
}
}
@TestMetadata("idea/testData/inspectionsLocal/replaceAssociateFunction/associateByToKeyAndValue")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class AssociateByToKeyAndValue extends AbstractLocalInspectionTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
}
public void testAllFilesPresentInAssociateByToKeyAndValue() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/inspectionsLocal/replaceAssociateFunction/associateByToKeyAndValue"), Pattern.compile("^([\\w\\-_]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
}
@TestMetadata("array.kt")
public void testArray() throws Exception {
runTest("idea/testData/inspectionsLocal/replaceAssociateFunction/associateByToKeyAndValue/array.kt");
}
@TestMetadata("basic.kt")
public void testBasic() throws Exception {
runTest("idea/testData/inspectionsLocal/replaceAssociateFunction/associateByToKeyAndValue/basic.kt");
}
@TestMetadata("basic2.kt")
public void testBasic2() throws Exception {
runTest("idea/testData/inspectionsLocal/replaceAssociateFunction/associateByToKeyAndValue/basic2.kt");
}
@TestMetadata("basic3.kt")
public void testBasic3() throws Exception {
runTest("idea/testData/inspectionsLocal/replaceAssociateFunction/associateByToKeyAndValue/basic3.kt");
}
@TestMetadata("basic4.kt")
public void testBasic4() throws Exception {
runTest("idea/testData/inspectionsLocal/replaceAssociateFunction/associateByToKeyAndValue/basic4.kt");
}
}
@TestMetadata("idea/testData/inspectionsLocal/replaceAssociateFunction/associateWith")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class AssociateWith extends AbstractLocalInspectionTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
}
public void testAllFilesPresentInAssociateWith() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/inspectionsLocal/replaceAssociateFunction/associateWith"), Pattern.compile("^([\\w\\-_]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
}
@TestMetadata("array.kt")
public void testArray() throws Exception {
runTest("idea/testData/inspectionsLocal/replaceAssociateFunction/associateWith/array.kt");
}
@TestMetadata("basic.kt")
public void testBasic() throws Exception {
runTest("idea/testData/inspectionsLocal/replaceAssociateFunction/associateWith/basic.kt");
}
@TestMetadata("basic2.kt")
public void testBasic2() throws Exception {
runTest("idea/testData/inspectionsLocal/replaceAssociateFunction/associateWith/basic2.kt");
}
@TestMetadata("basic3.kt")
public void testBasic3() throws Exception {
runTest("idea/testData/inspectionsLocal/replaceAssociateFunction/associateWith/basic3.kt");
}
@TestMetadata("basic4.kt")
public void testBasic4() throws Exception {
runTest("idea/testData/inspectionsLocal/replaceAssociateFunction/associateWith/basic4.kt");
}
@TestMetadata("basic5.kt")
public void testBasic5() throws Exception {
runTest("idea/testData/inspectionsLocal/replaceAssociateFunction/associateWith/basic5.kt");
}
@TestMetadata("intArray.kt")
public void testIntArray() throws Exception {
runTest("idea/testData/inspectionsLocal/replaceAssociateFunction/associateWith/intArray.kt");
}
@TestMetadata("labeledReturn.kt")
public void testLabeledReturn() throws Exception {
runTest("idea/testData/inspectionsLocal/replaceAssociateFunction/associateWith/labeledReturn.kt");
}
@TestMetadata("multiLine.kt")
public void testMultiLine() throws Exception {
runTest("idea/testData/inspectionsLocal/replaceAssociateFunction/associateWith/multiLine.kt");
}
@TestMetadata("notPair.kt")
public void testNotPair() throws Exception {
runTest("idea/testData/inspectionsLocal/replaceAssociateFunction/associateWith/notPair.kt");
}
@TestMetadata("sequence.kt")
public void testSequence() throws Exception {
runTest("idea/testData/inspectionsLocal/replaceAssociateFunction/associateWith/sequence.kt");
}
@TestMetadata("set.kt")
public void testSet() throws Exception {
runTest("idea/testData/inspectionsLocal/replaceAssociateFunction/associateWith/set.kt");
}
}
@TestMetadata("idea/testData/inspectionsLocal/replaceAssociateFunction/associateWithTo")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class AssociateWithTo extends AbstractLocalInspectionTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
}
public void testAllFilesPresentInAssociateWithTo() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/inspectionsLocal/replaceAssociateFunction/associateWithTo"), Pattern.compile("^([\\w\\-_]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
}
@TestMetadata("array.kt")
public void testArray() throws Exception {
runTest("idea/testData/inspectionsLocal/replaceAssociateFunction/associateWithTo/array.kt");
}
@TestMetadata("basic.kt")
public void testBasic() throws Exception {
runTest("idea/testData/inspectionsLocal/replaceAssociateFunction/associateWithTo/basic.kt");
}
@TestMetadata("basic2.kt")
public void testBasic2() throws Exception {
runTest("idea/testData/inspectionsLocal/replaceAssociateFunction/associateWithTo/basic2.kt");
}
@TestMetadata("basic3.kt")
public void testBasic3() throws Exception {
runTest("idea/testData/inspectionsLocal/replaceAssociateFunction/associateWithTo/basic3.kt");
}
@TestMetadata("basic4.kt")
public void testBasic4() throws Exception {
runTest("idea/testData/inspectionsLocal/replaceAssociateFunction/associateWithTo/basic4.kt");
}
@TestMetadata("basic5.kt")
public void testBasic5() throws Exception {
runTest("idea/testData/inspectionsLocal/replaceAssociateFunction/associateWithTo/basic5.kt");
}
}
}
@TestMetadata("idea/testData/inspectionsLocal/replaceNegatedIsEmptyWithIsNotEmpty")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)