Introduce "Useless call on collection type" inspection

Related to KT-12165
Supported functions: filterNotNull, filterIsInstance,
mapNotNull, mapNotNullTo, mapIndexedNotNull, mapIndexedNotNullTo

Also, "Useless cal on not-null" improved a bit
This commit is contained in:
Mikhail Glukhikh
2017-06-19 16:00:30 +03:00
parent f80f41d254
commit bdb9f00c75
32 changed files with 411 additions and 73 deletions
@@ -0,0 +1,5 @@
<html>
<body>
This inspection reports filter-like calls on already filtered collections, e.g. listOf("abc").filterNotNull()
</body>
</html>
+8
View File
@@ -2258,6 +2258,14 @@
language="kotlin" language="kotlin"
/> />
<localInspection implementationClass="org.jetbrains.kotlin.idea.inspections.collections.UselessCallOnCollectionInspection"
displayName="Useless call on collection type"
groupName="Kotlin"
enabledByDefault="true"
level="WARNING"
language="kotlin"
/>
<referenceImporter implementation="org.jetbrains.kotlin.idea.quickfix.KotlinReferenceImporter"/> <referenceImporter implementation="org.jetbrains.kotlin.idea.quickfix.KotlinReferenceImporter"/>
<fileType.fileViewProviderFactory filetype="KJSM" implementationClass="com.intellij.psi.ClassFileViewProviderFactory"/> <fileType.fileViewProviderFactory filetype="KJSM" implementationClass="com.intellij.psi.ClassFileViewProviderFactory"/>
@@ -0,0 +1,69 @@
/*
* Copyright 2010-2017 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.inspections.collections
import com.intellij.codeInspection.ProblemsHolder
import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.inspections.AbstractKotlinInspection
import org.jetbrains.kotlin.psi.KtCallExpression
import org.jetbrains.kotlin.psi.KtExpression
import org.jetbrains.kotlin.psi.KtQualifiedExpression
import org.jetbrains.kotlin.psi.KtVisitorVoid
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameOrNull
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
abstract class AbstractUselessCallInspection : AbstractKotlinInspection() {
protected abstract val uselessFqNames: Map<String, Conversion>
protected abstract val uselessNames: Set<String>
protected abstract fun QualifiedExpressionVisitor.suggestConversionIfNeeded(
expression: KtQualifiedExpression,
calleeExpression: KtExpression,
context: BindingContext,
conversion: Conversion
)
inner class QualifiedExpressionVisitor internal constructor(val holder: ProblemsHolder, val isOnTheFly: Boolean) : KtVisitorVoid() {
override fun visitQualifiedExpression(expression: KtQualifiedExpression) {
super.visitQualifiedExpression(expression)
val selector = expression.selectorExpression as? KtCallExpression ?: return
val calleeExpression = selector.calleeExpression ?: return
if (calleeExpression.text !in uselessNames) return
val context = expression.analyze(BodyResolveMode.PARTIAL)
val resolvedCall = expression.getResolvedCall(context) ?: return
val conversion = uselessFqNames[resolvedCall.resultingDescriptor.fqNameOrNull()?.asString()] ?: return
suggestConversionIfNeeded(expression, calleeExpression, context, conversion)
}
}
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean) = QualifiedExpressionVisitor(holder, isOnTheFly)
protected companion object {
data class Conversion(val replacementName: String? = null)
val deleteConversion = Conversion()
fun Set<String>.toShortNames() = mapTo(mutableSetOf()) { fqName -> fqName.takeLastWhile { it != '.' } }
}
}
@@ -20,10 +20,9 @@ import com.intellij.codeInspection.LocalQuickFix
import com.intellij.codeInspection.ProblemDescriptor import com.intellij.codeInspection.ProblemDescriptor
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.idea.core.replaced import org.jetbrains.kotlin.idea.core.replaced
import org.jetbrains.kotlin.psi.KtCallExpression
import org.jetbrains.kotlin.psi.KtPsiFactory import org.jetbrains.kotlin.psi.KtPsiFactory
import org.jetbrains.kotlin.psi.KtQualifiedExpression import org.jetbrains.kotlin.psi.KtQualifiedExpression
import org.jetbrains.kotlin.psi.KtSafeQualifiedExpression
import org.jetbrains.kotlin.psi.createExpressionByPattern
class RenameUselessCallFix(val newName: String) : LocalQuickFix { class RenameUselessCallFix(val newName: String) : LocalQuickFix {
override fun getName() = "Rename useless call to '$newName'" override fun getName() = "Rename useless call to '$newName'"
@@ -33,8 +32,9 @@ class RenameUselessCallFix(val newName: String) : LocalQuickFix {
override fun applyFix(project: Project, descriptor: ProblemDescriptor) { override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
(descriptor.psiElement as? KtQualifiedExpression)?.let { (descriptor.psiElement as? KtQualifiedExpression)?.let {
val factory = KtPsiFactory(it) val factory = KtPsiFactory(it)
val sign = if (it is KtSafeQualifiedExpression) "?." else "." val selectorCallExpression = it.selectorExpression as? KtCallExpression
it.replaced(factory.createExpressionByPattern("$0$sign$newName()", it.receiverExpression)) val calleeExpression = selectorCallExpression?.calleeExpression ?: return
calleeExpression.replaced(factory.createExpression(newName))
} }
} }
} }
@@ -0,0 +1,100 @@
/*
* Copyright 2010-2017 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.inspections.collections
import com.intellij.codeInspection.ProblemHighlightType
import com.intellij.openapi.util.TextRange
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.builtins.getFunctionalClassKind
import org.jetbrains.kotlin.builtins.isFunctionType
import org.jetbrains.kotlin.psi.KtExpression
import org.jetbrains.kotlin.psi.KtQualifiedExpression
import org.jetbrains.kotlin.psi.psiUtil.endOffset
import org.jetbrains.kotlin.psi.psiUtil.startOffset
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.calls.callUtil.getType
import org.jetbrains.kotlin.types.TypeUtils
import org.jetbrains.kotlin.types.isFlexible
import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
class UselessCallOnCollectionInspection : AbstractUselessCallInspection() {
override val uselessFqNames = mapOf("kotlin.collections.filterNotNull" to deleteConversion,
"kotlin.collections.filterIsInstance" to deleteConversion,
"kotlin.collections.mapNotNull" to Conversion("map"),
"kotlin.collections.mapNotNullTo" to Conversion("mapTo"),
"kotlin.collections.mapIndexedNotNull" to Conversion("mapIndexed"),
"kotlin.collections.mapIndexedNotNullTo" to Conversion("mapIndexedTo"))
override val uselessNames = uselessFqNames.keys.toShortNames()
override fun QualifiedExpressionVisitor.suggestConversionIfNeeded(
expression: KtQualifiedExpression,
calleeExpression: KtExpression,
context: BindingContext,
conversion: Conversion
) {
val receiverType = expression.receiverExpression.getType(context) ?: return
val receiverTypeArgument = receiverType.arguments.singleOrNull()?.type ?: return
val resolvedCall = expression.getResolvedCall(context) ?: return
if (calleeExpression.text == "filterIsInstance") {
val typeParameterDescriptor = resolvedCall.candidateDescriptor.typeParameters.singleOrNull() ?: return
val argumentType = resolvedCall.typeArguments[typeParameterDescriptor] ?: return
if (receiverTypeArgument.isFlexible() || !receiverTypeArgument.isSubtypeOf(argumentType)) return
}
else {
// xxxNotNull
if (TypeUtils.isNullableType(receiverTypeArgument)) return
if (calleeExpression.text != "filterNotNull") {
// Also check last argument functional type to have not-null result
val lastParameter = resolvedCall.resultingDescriptor.valueParameters.lastOrNull() ?: return
val lastArgument = resolvedCall.valueArguments[lastParameter]?.arguments?.singleOrNull() ?: return
val functionalType = lastArgument.getArgumentExpression()?.getType(context) ?: return
// Both Function & KFunction must pass here
if (functionalType.constructor.declarationDescriptor?.getFunctionalClassKind() == null) return
val resultType = functionalType.arguments.lastOrNull()?.type ?: return
if (TypeUtils.isNullableType(resultType)) return
}
}
val newName = conversion.replacementName
if (newName != null) {
val descriptor = holder.manager.createProblemDescriptor(
expression,
TextRange(expression.operationTokenNode.startOffset - expression.startOffset,
calleeExpression.endOffset - expression.startOffset),
"Call on collection type may be reduced",
ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
isOnTheFly,
RenameUselessCallFix(newName)
)
holder.registerProblem(descriptor)
}
else {
val descriptor = holder.manager.createProblemDescriptor(
expression,
TextRange(expression.operationTokenNode.startOffset - expression.startOffset,
calleeExpression.endOffset - expression.startOffset),
"Useless call on collection type",
ProblemHighlightType.LIKE_UNUSED_SYMBOL,
isOnTheFly,
RemoveUselessCallFix()
)
holder.registerProblem(descriptor)
}
}
}
@@ -18,88 +18,70 @@ package org.jetbrains.kotlin.idea.inspections.collections
import com.intellij.codeInspection.IntentionWrapper import com.intellij.codeInspection.IntentionWrapper
import com.intellij.codeInspection.ProblemHighlightType import com.intellij.codeInspection.ProblemHighlightType
import com.intellij.codeInspection.ProblemsHolder
import com.intellij.openapi.util.TextRange import com.intellij.openapi.util.TextRange
import com.intellij.psi.PsiElementVisitor
import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.inspections.AbstractKotlinInspection
import org.jetbrains.kotlin.idea.quickfix.ReplaceWithDotCallFix import org.jetbrains.kotlin.idea.quickfix.ReplaceWithDotCallFix
import org.jetbrains.kotlin.psi.KtCallExpression import org.jetbrains.kotlin.psi.KtExpression
import org.jetbrains.kotlin.psi.KtQualifiedExpression import org.jetbrains.kotlin.psi.KtQualifiedExpression
import org.jetbrains.kotlin.psi.KtSafeQualifiedExpression import org.jetbrains.kotlin.psi.KtSafeQualifiedExpression
import org.jetbrains.kotlin.psi.KtVisitorVoid
import org.jetbrains.kotlin.psi.psiUtil.endOffset import org.jetbrains.kotlin.psi.psiUtil.endOffset
import org.jetbrains.kotlin.psi.psiUtil.startOffset import org.jetbrains.kotlin.psi.psiUtil.startOffset
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.calls.callUtil.getType import org.jetbrains.kotlin.resolve.calls.callUtil.getType
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameOrNull
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.types.TypeUtils import org.jetbrains.kotlin.types.TypeUtils
class UselessCallOnNotNullInspection : AbstractKotlinInspection() { class UselessCallOnNotNullInspection : AbstractUselessCallInspection() {
override val uselessFqNames = mapOf("kotlin.collections.orEmpty" to deleteConversion,
"kotlin.text.orEmpty" to deleteConversion,
"kotlin.text.isNullOrEmpty" to Conversion("isEmpty"),
"kotlin.text.isNullOrBlank" to Conversion("isBlank"))
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor { override val uselessNames = uselessFqNames.keys.toShortNames()
return object : KtVisitorVoid() {
override fun visitQualifiedExpression(expression: KtQualifiedExpression) {
super.visitQualifiedExpression(expression)
val selector = expression.selectorExpression as? KtCallExpression ?: return
val calleeExpression = selector.calleeExpression ?: return
if (calleeExpression.text !in names) return
val context = expression.analyze(BodyResolveMode.PARTIAL) override fun QualifiedExpressionVisitor.suggestConversionIfNeeded(
val resolvedCall = expression.getResolvedCall(context) ?: return expression: KtQualifiedExpression,
val conversion = fqNames[resolvedCall.resultingDescriptor.fqNameOrNull()?.asString()] ?: return calleeExpression: KtExpression,
val newName = conversion.replacementName context: BindingContext,
conversion: Conversion
) {
val newName = conversion.replacementName
val safeExpression = expression as? KtSafeQualifiedExpression val safeExpression = expression as? KtSafeQualifiedExpression
val notNullType = expression.receiverExpression.getType(context)?.let { TypeUtils.isNullableType(it) } == false val notNullType = expression.receiverExpression.getType(context)?.let { TypeUtils.isNullableType(it) } == false
if (newName != null && (notNullType || safeExpression != null)) { val defaultRange = TextRange(expression.operationTokenNode.startOffset, calleeExpression.endOffset)
val descriptor = holder.manager.createProblemDescriptor( .shiftRight(-expression.startOffset)
expression, if (newName != null && (notNullType || safeExpression != null)) {
TextRange(expression.operationTokenNode.startOffset - expression.startOffset, val fixes = listOf(RenameUselessCallFix(newName)) + listOfNotNull(safeExpression?.let {
calleeExpression.endOffset - expression.startOffset), IntentionWrapper(ReplaceWithDotCallFix(safeExpression), safeExpression.containingKtFile)
"Call on not-null type may be reduced", })
ProblemHighlightType.GENERIC_ERROR_OR_WARNING, val descriptor = holder.manager.createProblemDescriptor(
isOnTheFly, expression,
RenameUselessCallFix(newName) defaultRange,
) "Call on not-null type may be reduced",
holder.registerProblem(descriptor) ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
} isOnTheFly,
else if (notNullType) { *fixes.toTypedArray()
val descriptor = holder.manager.createProblemDescriptor( )
expression, holder.registerProblem(descriptor)
TextRange(expression.operationTokenNode.startOffset - expression.startOffset, }
calleeExpression.endOffset - expression.startOffset), else if (notNullType) {
"Useless call on not-null type", val descriptor = holder.manager.createProblemDescriptor(
ProblemHighlightType.LIKE_UNUSED_SYMBOL, expression,
isOnTheFly, defaultRange,
RemoveUselessCallFix() "Useless call on not-null type",
) ProblemHighlightType.LIKE_UNUSED_SYMBOL,
holder.registerProblem(descriptor) isOnTheFly,
} RemoveUselessCallFix()
else if (safeExpression != null) { )
holder.registerProblem( holder.registerProblem(descriptor)
safeExpression.operationTokenNode.psi, }
"This call is useless with ?.", else if (safeExpression != null) {
ProblemHighlightType.GENERIC_ERROR_OR_WARNING, holder.registerProblem(
IntentionWrapper(ReplaceWithDotCallFix(safeExpression), safeExpression.containingKtFile) safeExpression.operationTokenNode.psi,
) "This call is useless with ?.",
} ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
} IntentionWrapper(ReplaceWithDotCallFix(safeExpression), safeExpression.containingKtFile)
)
} }
}
companion object {
private data class Conversion(val replacementName: String? = null)
private val deleteConversion = Conversion()
private val fqNames = mapOf("kotlin.collections.orEmpty" to deleteConversion,
"kotlin.text.orEmpty" to deleteConversion,
"kotlin.text.isNullOrEmpty" to Conversion("isEmpty"),
"kotlin.text.isNullOrBlank" to Conversion("isBlank"))
private val names = fqNames.keys.mapTo(mutableSetOf()) { fqName -> fqName.takeLastWhile { it != '.' } }
} }
} }
@@ -0,0 +1 @@
org.jetbrains.kotlin.idea.inspections.collections.UselessCallOnCollectionInspection
@@ -0,0 +1,3 @@
// WITH_RUNTIME
val x = listOf("1").<caret>filterIsInstance<String>()
@@ -0,0 +1,3 @@
// WITH_RUNTIME
val x = listOf("1")
@@ -0,0 +1,4 @@
// PROBLEM: none
// WITH_RUNTIME
val x = listOf(true, "1").<caret>filterIsInstance<String>()
@@ -0,0 +1,4 @@
// PROBLEM: none
// WITH_RUNTIME
val x = listOf(System.getProperty("")).<caret>filterIsInstance<String>()
@@ -0,0 +1,3 @@
// WITH_RUNTIME
val x = listOf("1").<caret>filterIsInstance<Any>()
@@ -0,0 +1,3 @@
// WITH_RUNTIME
val x = listOf("1")
@@ -0,0 +1,4 @@
// PROBLEM: none
// WITH_RUNTIME
val x = listOf("1", null).<caret>filterIsInstance<Any>()
@@ -0,0 +1,3 @@
// WITH_RUNTIME
val x = listOf("1").<caret>filterNotNull()
@@ -0,0 +1,3 @@
// WITH_RUNTIME
val x = listOf("1")
@@ -0,0 +1,3 @@
// WITH_RUNTIME
val someList = listOf("alpha", "beta").<caret>mapIndexedNotNullTo(destination = hashSetOf()) { index, value -> index + value.length }
@@ -0,0 +1,3 @@
// WITH_RUNTIME
val someList = listOf("alpha", "beta").mapIndexedTo(destination = hashSetOf()) { index, value -> index + value.length }
@@ -0,0 +1,3 @@
// WITH_RUNTIME
val x = listOf("1").<caret>mapNotNullTo(mutableSetOf()) { it.toInt() }
@@ -0,0 +1,3 @@
// WITH_RUNTIME
val x = listOf("1").mapTo(mutableSetOf()) { it.toInt() }
@@ -0,0 +1,3 @@
// WITH_RUNTIME
val x = listOf("1").<caret>mapNotNull { it.toInt() }
@@ -0,0 +1,3 @@
// WITH_RUNTIME
val x = listOf("1").map { it.toInt() }
@@ -0,0 +1,4 @@
// PROBLEM: none
// WITH_RUNTIME
val x = listOf("1").<caret>mapNotNull { if (it.isNotEmpty()) it.toInt() else null }
@@ -0,0 +1,3 @@
// WITH_RUNTIME
val x = listOf("1").<caret>mapNotNull(String::toInt)
@@ -0,0 +1,3 @@
// WITH_RUNTIME
val x = listOf("1").map(String::toInt)
@@ -0,0 +1,6 @@
// PROBLEM: none
// WITH_RUNTIME
fun String.toNullableInt(): Int? = null
val x = listOf("1").<caret>mapNotNull(String::toNullableInt)
@@ -0,0 +1,4 @@
// PROBLEM: none
// WITH_RUNTIME
val x = listOf("1", null).<caret>filterNotNull()
@@ -1,4 +1,5 @@
// WITH_RUNTIME // WITH_RUNTIME
// FIX: Rename useless call to 'isBlank'
val s: String? = "" val s: String? = ""
val blank = s<caret>?.isNullOrBlank() val blank = s<caret>?.isNullOrBlank()
@@ -1,4 +1,5 @@
// WITH_RUNTIME // WITH_RUNTIME
// FIX: Rename useless call to 'isBlank'
val s: String? = "" val s: String? = ""
val blank = s?.isBlank() val blank = s?.isBlank()
@@ -0,0 +1,5 @@
// WITH_RUNTIME
// FIX: Replace with dot call
val s: String? = ""
val empty = s<caret>?.isNullOrEmpty()
@@ -0,0 +1,5 @@
// WITH_RUNTIME
// FIX: Replace with dot call
val s: String? = ""
val empty = s.isNullOrEmpty()
@@ -59,6 +59,93 @@ public class LocalInspectionTestGenerated extends AbstractLocalInspectionTest {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/inspectionsLocal/collections"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), TargetBackend.ANY, true); KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/inspectionsLocal/collections"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), TargetBackend.ANY, true);
} }
@TestMetadata("idea/testData/inspectionsLocal/collections/uselessCallOnCollection")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class UselessCallOnCollection extends AbstractLocalInspectionTest {
public void testAllFilesPresentInUselessCallOnCollection() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/inspectionsLocal/collections/uselessCallOnCollection"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), TargetBackend.ANY, true);
}
@TestMetadata("FilterIsExactInstance.kt")
public void testFilterIsExactInstance() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/collections/uselessCallOnCollection/FilterIsExactInstance.kt");
doTest(fileName);
}
@TestMetadata("FilterIsExactInstanceFake.kt")
public void testFilterIsExactInstanceFake() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/collections/uselessCallOnCollection/FilterIsExactInstanceFake.kt");
doTest(fileName);
}
@TestMetadata("FilterIsForFlexible.kt")
public void testFilterIsForFlexible() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/collections/uselessCallOnCollection/FilterIsForFlexible.kt");
doTest(fileName);
}
@TestMetadata("FilterIsSupertypeInstance.kt")
public void testFilterIsSupertypeInstance() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/collections/uselessCallOnCollection/FilterIsSupertypeInstance.kt");
doTest(fileName);
}
@TestMetadata("FilterIsSupertypeInstanceFake.kt")
public void testFilterIsSupertypeInstanceFake() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/collections/uselessCallOnCollection/FilterIsSupertypeInstanceFake.kt");
doTest(fileName);
}
@TestMetadata("FilterNotNull.kt")
public void testFilterNotNull() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/collections/uselessCallOnCollection/FilterNotNull.kt");
doTest(fileName);
}
@TestMetadata("filterNotNullFake.kt")
public void testFilterNotNullFake() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/collections/uselessCallOnCollection/filterNotNullFake.kt");
doTest(fileName);
}
@TestMetadata("MapIndexedNotNullTo.kt")
public void testMapIndexedNotNullTo() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/collections/uselessCallOnCollection/MapIndexedNotNullTo.kt");
doTest(fileName);
}
@TestMetadata("MapNotNullTo.kt")
public void testMapNotNullTo() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/collections/uselessCallOnCollection/MapNotNullTo.kt");
doTest(fileName);
}
@TestMetadata("MapNotNullWithLambda.kt")
public void testMapNotNullWithLambda() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/collections/uselessCallOnCollection/MapNotNullWithLambda.kt");
doTest(fileName);
}
@TestMetadata("MapNotNullWithLambdaFake.kt")
public void testMapNotNullWithLambdaFake() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/collections/uselessCallOnCollection/MapNotNullWithLambdaFake.kt");
doTest(fileName);
}
@TestMetadata("MapNotNullWithReference.kt")
public void testMapNotNullWithReference() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/collections/uselessCallOnCollection/MapNotNullWithReference.kt");
doTest(fileName);
}
@TestMetadata("MapNotNullWithReferenceFake.kt")
public void testMapNotNullWithReferenceFake() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/collections/uselessCallOnCollection/MapNotNullWithReferenceFake.kt");
doTest(fileName);
}
}
@TestMetadata("idea/testData/inspectionsLocal/collections/uselessCallOnNotNull") @TestMetadata("idea/testData/inspectionsLocal/collections/uselessCallOnNotNull")
@TestDataPath("$PROJECT_ROOT") @TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class) @RunWith(JUnit3RunnerWithInners.class)
@@ -97,6 +184,12 @@ public class LocalInspectionTestGenerated extends AbstractLocalInspectionTest {
doTest(fileName); doTest(fileName);
} }
@TestMetadata("NullOrEmptySafe.kt")
public void testNullOrEmptySafe() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/collections/uselessCallOnNotNull/NullOrEmptySafe.kt");
doTest(fileName);
}
@TestMetadata("OrEmptyFake.kt") @TestMetadata("OrEmptyFake.kt")
public void testOrEmptyFake() throws Exception { public void testOrEmptyFake() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/collections/uselessCallOnNotNull/OrEmptyFake.kt"); String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/collections/uselessCallOnNotNull/OrEmptyFake.kt");