Introduce "Unused result of data class copy" inspection
#KT-34121 Fixed
This commit is contained in:
committed by
klunnii
parent
ae6d89b100
commit
bc580d2fd9
@@ -2216,4 +2216,5 @@ hints.codevision.inheritors.format={0, choice, 1#1 Inheritor|2#{0,number} Inheri
|
||||
hints.codevision.inheritors.to_many.format={0,number}+ Inheritors
|
||||
hints.codevision.overrides.format={0, choice, 1#1 Override|2#{0,number} Overrides}
|
||||
hints.codevision.overrides.to_many.format={0,number}+ Overrides
|
||||
hints.codevision.settings=Settings...
|
||||
hints.codevision.settings=Settings...
|
||||
inspection.unused.result.of.data.class.copy=Unused result of data class copy
|
||||
@@ -2563,6 +2563,14 @@
|
||||
language="kotlin"
|
||||
key="inspection.simplifiable.scope.function.display.name" bundle="messages.KotlinBundle"/>
|
||||
|
||||
<localInspection implementationClass="org.jetbrains.kotlin.idea.inspections.UnusedDataClassCopyResultInspection"
|
||||
groupPath="Kotlin"
|
||||
groupName="Probable bugs"
|
||||
enabledByDefault="true"
|
||||
level="WARNING"
|
||||
language="kotlin"
|
||||
key="inspection.unused.result.of.data.class.copy" bundle="messages.KotlinBundle"/>
|
||||
|
||||
</extensions>
|
||||
|
||||
</idea-plugin>
|
||||
@@ -0,0 +1,5 @@
|
||||
<html>
|
||||
<body>
|
||||
This inspection reports unused result of data class copy function call.
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.ProblemsHolder
|
||||
import org.jetbrains.kotlin.idea.KotlinBundle
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.psi.callExpressionVisitor
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForSelectorOrThis
|
||||
import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsExpression
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitClassReceiver
|
||||
|
||||
class UnusedDataClassCopyResultInspection : AbstractKotlinInspection() {
|
||||
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean) = callExpressionVisitor(fun(call) {
|
||||
val callee = call.calleeExpression ?: return
|
||||
if (callee.text != "copy") return
|
||||
val context = call.analyze(BodyResolveMode.PARTIAL_WITH_CFA)
|
||||
val descriptor = call.getResolvedCall(context)?.resultingDescriptor ?: return
|
||||
val receiver = descriptor.dispatchReceiverParameter ?: descriptor.extensionReceiverParameter ?: return
|
||||
if ((receiver.value as? ImplicitClassReceiver)?.classDescriptor?.isData != true) return
|
||||
if (call.getQualifiedExpressionForSelectorOrThis().isUsedAsExpression(context)) return
|
||||
holder.registerProblem(callee, KotlinBundle.message("inspection.unused.result.of.data.class.copy"))
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
org.jetbrains.kotlin.idea.inspections.UnusedDataClassCopyResultInspection
|
||||
@@ -0,0 +1,11 @@
|
||||
// FIX: none
|
||||
// WITH_RUNTIME
|
||||
fun main() {
|
||||
val o = Foo("")
|
||||
o.<caret>copy(prop = "New")
|
||||
bar(o)
|
||||
}
|
||||
|
||||
data class Foo(val prop: String)
|
||||
|
||||
fun bar(foo: Foo) {}
|
||||
@@ -0,0 +1,13 @@
|
||||
// FIX: none
|
||||
// WITH_RUNTIME
|
||||
fun main() {
|
||||
val o = Foo("")
|
||||
o.run {
|
||||
<caret>copy(prop = "New")
|
||||
bar(o)
|
||||
}
|
||||
}
|
||||
|
||||
data class Foo(val prop: String)
|
||||
|
||||
fun bar(foo: Foo) {}
|
||||
@@ -0,0 +1,11 @@
|
||||
// PROBLEM: none
|
||||
// WITH_RUNTIME
|
||||
fun main() {
|
||||
val o = Foo("")
|
||||
val o2 = o.<caret>copy(prop = "New")
|
||||
bar(o2)
|
||||
}
|
||||
|
||||
data class Foo(val prop: String)
|
||||
|
||||
fun bar(foo: Foo) {}
|
||||
@@ -0,0 +1,13 @@
|
||||
// PROBLEM: none
|
||||
// WITH_RUNTIME
|
||||
fun main() {
|
||||
val o = Foo("")
|
||||
o.run {
|
||||
val o2 = <caret>copy(prop = "New")
|
||||
bar(o2)
|
||||
}
|
||||
}
|
||||
|
||||
data class Foo(val prop: String)
|
||||
|
||||
fun bar(foo: Foo) {}
|
||||
+33
@@ -14026,6 +14026,39 @@ public class LocalInspectionTestGenerated extends AbstractLocalInspectionTest {
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/inspectionsLocal/unusedDataClassCopyResult")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class UnusedDataClassCopyResult extends AbstractLocalInspectionTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInUnusedDataClassCopyResult() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/testData/inspectionsLocal/unusedDataClassCopyResult"), Pattern.compile("^([\\w\\-_]+)\\.(kt|kts)$"), null, true);
|
||||
}
|
||||
|
||||
@TestMetadata("basic.kt")
|
||||
public void testBasic() throws Exception {
|
||||
runTest("idea/testData/inspectionsLocal/unusedDataClassCopyResult/basic.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("basic2.kt")
|
||||
public void testBasic2() throws Exception {
|
||||
runTest("idea/testData/inspectionsLocal/unusedDataClassCopyResult/basic2.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("used.kt")
|
||||
public void testUsed() throws Exception {
|
||||
runTest("idea/testData/inspectionsLocal/unusedDataClassCopyResult/used.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("used2.kt")
|
||||
public void testUsed2() throws Exception {
|
||||
runTest("idea/testData/inspectionsLocal/unusedDataClassCopyResult/used2.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/inspectionsLocal/unusedEquals")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
Reference in New Issue
Block a user