Augmented list assignment inspection: add "replace with ordinary" fix
Relates to KT-20626
This commit is contained in:
+8
-14
@@ -5,10 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.idea.inspections
|
package org.jetbrains.kotlin.idea.inspections
|
||||||
|
|
||||||
import com.intellij.codeInspection.LocalQuickFix
|
import com.intellij.codeInspection.*
|
||||||
import com.intellij.codeInspection.ProblemDescriptor
|
|
||||||
import com.intellij.codeInspection.ProblemHighlightType
|
|
||||||
import com.intellij.codeInspection.ProblemsHolder
|
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.psi.PsiElementVisitor
|
import com.intellij.psi.PsiElementVisitor
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
@@ -17,15 +14,13 @@ import org.jetbrains.kotlin.diagnostics.Severity
|
|||||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveToCall
|
import org.jetbrains.kotlin.idea.caches.resolve.resolveToCall
|
||||||
import org.jetbrains.kotlin.idea.core.replaced
|
import org.jetbrains.kotlin.idea.core.replaced
|
||||||
|
import org.jetbrains.kotlin.idea.intentions.ReplaceWithOrdinaryAssignmentIntention
|
||||||
import org.jetbrains.kotlin.idea.project.builtIns
|
import org.jetbrains.kotlin.idea.project.builtIns
|
||||||
import org.jetbrains.kotlin.idea.references.mainReference
|
import org.jetbrains.kotlin.idea.references.mainReference
|
||||||
import org.jetbrains.kotlin.lexer.KtSingleValueToken
|
import org.jetbrains.kotlin.lexer.KtSingleValueToken
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.anyDescendantOfType
|
import org.jetbrains.kotlin.psi.psiUtil.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getPrevSiblingIgnoringWhitespaceAndComments
|
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.siblings
|
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getType
|
import org.jetbrains.kotlin.resolve.calls.callUtil.getType
|
||||||
@@ -60,11 +55,10 @@ class SuspiciousCollectionReassignmentInspection : AbstractKotlinInspection() {
|
|||||||
if (ReplaceWithFilterFix.isApplicable(binaryExpression, leftDefaultType, context)) {
|
if (ReplaceWithFilterFix.isApplicable(binaryExpression, leftDefaultType, context)) {
|
||||||
fixes.add(ReplaceWithFilterFix())
|
fixes.add(ReplaceWithFilterFix())
|
||||||
}
|
}
|
||||||
if (ReplaceWithAssignmentFix.isApplicable(binaryExpression, property, context)) {
|
when {
|
||||||
fixes.add(ReplaceWithAssignmentFix())
|
ReplaceWithAssignmentFix.isApplicable(binaryExpression, property, context) -> fixes.add(ReplaceWithAssignmentFix())
|
||||||
}
|
JoinWithInitializerFix.isApplicable(binaryExpression, property) -> fixes.add(JoinWithInitializerFix(operationToken))
|
||||||
if (JoinWithInitializerFix.isApplicable(binaryExpression, property)) {
|
else -> fixes.add(IntentionWrapper(ReplaceWithOrdinaryAssignmentIntention(), binaryExpression.containingKtFile))
|
||||||
fixes.add(JoinWithInitializerFix(operationToken))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val typeText = leftDefaultType.toString().takeWhile { it != '<' }.toLowerCase()
|
val typeText = leftDefaultType.toString().takeWhile { it != '<' }.toLowerCase()
|
||||||
@@ -150,7 +144,7 @@ class SuspiciousCollectionReassignmentInspection : AbstractKotlinInspection() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private class ReplaceWithAssignmentFix : LocalQuickFix {
|
private class ReplaceWithAssignmentFix : LocalQuickFix {
|
||||||
override fun getName() = "Replace with assignment"
|
override fun getName() = "Replace with assignment (original is empty)"
|
||||||
|
|
||||||
override fun getFamilyName() = name
|
override fun getFamilyName() = name
|
||||||
|
|
||||||
|
|||||||
Vendored
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
// "Replace with assignment" "false"
|
// "Replace with assignment (original is empty)" "false"
|
||||||
// TOOL: org.jetbrains.kotlin.idea.inspections.SuspiciousCollectionReassignmentInspection
|
// TOOL: org.jetbrains.kotlin.idea.inspections.SuspiciousCollectionReassignmentInspection
|
||||||
// ACTION: Change type to mutable
|
// ACTION: Change type to mutable
|
||||||
// ACTION: Replace overloaded operator with function call
|
// ACTION: Replace overloaded operator with function call
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
// "Replace with assignment" "true"
|
// "Replace with assignment (original is empty)" "true"
|
||||||
// TOOL: org.jetbrains.kotlin.idea.inspections.SuspiciousCollectionReassignmentInspection
|
// TOOL: org.jetbrains.kotlin.idea.inspections.SuspiciousCollectionReassignmentInspection
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
fun test(otherList: List<Int>) {
|
fun test(otherList: List<Int>) {
|
||||||
|
|||||||
Vendored
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
// "Replace with assignment" "true"
|
// "Replace with assignment (original is empty)" "true"
|
||||||
// TOOL: org.jetbrains.kotlin.idea.inspections.SuspiciousCollectionReassignmentInspection
|
// TOOL: org.jetbrains.kotlin.idea.inspections.SuspiciousCollectionReassignmentInspection
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
fun test(otherList: List<Int>) {
|
fun test(otherList: List<Int>) {
|
||||||
|
|||||||
Vendored
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
// "Replace with assignment" "true"
|
// "Replace with assignment (original is empty)" "true"
|
||||||
// TOOL: org.jetbrains.kotlin.idea.inspections.SuspiciousCollectionReassignmentInspection
|
// TOOL: org.jetbrains.kotlin.idea.inspections.SuspiciousCollectionReassignmentInspection
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
fun test(otherList: List<Int>) {
|
fun test(otherList: List<Int>) {
|
||||||
|
|||||||
Vendored
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
// "Replace with assignment" "true"
|
// "Replace with assignment (original is empty)" "true"
|
||||||
// TOOL: org.jetbrains.kotlin.idea.inspections.SuspiciousCollectionReassignmentInspection
|
// TOOL: org.jetbrains.kotlin.idea.inspections.SuspiciousCollectionReassignmentInspection
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
fun test(otherList: List<Int>) {
|
fun test(otherList: List<Int>) {
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
// "Replace with assignment" "true"
|
// "Replace with assignment (original is empty)" "true"
|
||||||
// TOOL: org.jetbrains.kotlin.idea.inspections.SuspiciousCollectionReassignmentInspection
|
// TOOL: org.jetbrains.kotlin.idea.inspections.SuspiciousCollectionReassignmentInspection
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
fun test(otherMap: Map<Int, Int>) {
|
fun test(otherMap: Map<Int, Int>) {
|
||||||
|
|||||||
Vendored
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
// "Replace with assignment" "true"
|
// "Replace with assignment (original is empty)" "true"
|
||||||
// TOOL: org.jetbrains.kotlin.idea.inspections.SuspiciousCollectionReassignmentInspection
|
// TOOL: org.jetbrains.kotlin.idea.inspections.SuspiciousCollectionReassignmentInspection
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
fun test(otherMap: Map<Int, Int>) {
|
fun test(otherMap: Map<Int, Int>) {
|
||||||
|
|||||||
Vendored
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
// "Replace with assignment" "true"
|
// "Replace with assignment (original is empty)" "true"
|
||||||
// TOOL: org.jetbrains.kotlin.idea.inspections.SuspiciousCollectionReassignmentInspection
|
// TOOL: org.jetbrains.kotlin.idea.inspections.SuspiciousCollectionReassignmentInspection
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
fun test(otherMap: Map<Int, Int>) {
|
fun test(otherMap: Map<Int, Int>) {
|
||||||
|
|||||||
Vendored
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
// "Replace with assignment" "true"
|
// "Replace with assignment (original is empty)" "true"
|
||||||
// TOOL: org.jetbrains.kotlin.idea.inspections.SuspiciousCollectionReassignmentInspection
|
// TOOL: org.jetbrains.kotlin.idea.inspections.SuspiciousCollectionReassignmentInspection
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
fun test(otherMap: Map<Int, Int>) {
|
fun test(otherMap: Map<Int, Int>) {
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
// "Replace with assignment" "true"
|
// "Replace with assignment (original is empty)" "true"
|
||||||
// TOOL: org.jetbrains.kotlin.idea.inspections.SuspiciousCollectionReassignmentInspection
|
// TOOL: org.jetbrains.kotlin.idea.inspections.SuspiciousCollectionReassignmentInspection
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
fun test(otherList: Set<Int>) {
|
fun test(otherList: Set<Int>) {
|
||||||
|
|||||||
Vendored
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
// "Replace with assignment" "true"
|
// "Replace with assignment (original is empty)" "true"
|
||||||
// TOOL: org.jetbrains.kotlin.idea.inspections.SuspiciousCollectionReassignmentInspection
|
// TOOL: org.jetbrains.kotlin.idea.inspections.SuspiciousCollectionReassignmentInspection
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
fun test(otherList: Set<Int>) {
|
fun test(otherList: Set<Int>) {
|
||||||
|
|||||||
Vendored
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
// "Replace with assignment" "true"
|
// "Replace with assignment (original is empty)" "true"
|
||||||
// TOOL: org.jetbrains.kotlin.idea.inspections.SuspiciousCollectionReassignmentInspection
|
// TOOL: org.jetbrains.kotlin.idea.inspections.SuspiciousCollectionReassignmentInspection
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
fun test(otherList: Set<Int>) {
|
fun test(otherList: Set<Int>) {
|
||||||
|
|||||||
Vendored
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
// "Replace with assignment" "true"
|
// "Replace with assignment (original is empty)" "true"
|
||||||
// TOOL: org.jetbrains.kotlin.idea.inspections.SuspiciousCollectionReassignmentInspection
|
// TOOL: org.jetbrains.kotlin.idea.inspections.SuspiciousCollectionReassignmentInspection
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
fun test(otherList: Set<Int>) {
|
fun test(otherList: Set<Int>) {
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
// "Replace with assignment" "false"
|
// "Replace with assignment (original is empty)" "false"
|
||||||
// TOOL: org.jetbrains.kotlin.idea.inspections.SuspiciousCollectionReassignmentInspection
|
// TOOL: org.jetbrains.kotlin.idea.inspections.SuspiciousCollectionReassignmentInspection
|
||||||
// ACTION: Change type to mutable
|
// ACTION: Change type to mutable
|
||||||
// ACTION: Replace overloaded operator with function call
|
// ACTION: Replace overloaded operator with function call
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
// "Replace with assignment" "false"
|
// "Replace with assignment (original is empty)" "false"
|
||||||
// TOOL: org.jetbrains.kotlin.idea.inspections.SuspiciousCollectionReassignmentInspection
|
// TOOL: org.jetbrains.kotlin.idea.inspections.SuspiciousCollectionReassignmentInspection
|
||||||
// ACTION: Change type to mutable
|
// ACTION: Change type to mutable
|
||||||
// ACTION: Replace overloaded operator with function call
|
// ACTION: Replace overloaded operator with function call
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
// "Replace with assignment" "false"
|
// "Replace with assignment (original is empty)" "false"
|
||||||
// TOOL: org.jetbrains.kotlin.idea.inspections.SuspiciousCollectionReassignmentInspection
|
// TOOL: org.jetbrains.kotlin.idea.inspections.SuspiciousCollectionReassignmentInspection
|
||||||
// ACTION: Change type to mutable
|
// ACTION: Change type to mutable
|
||||||
// ACTION: Replace overloaded operator with function call
|
// ACTION: Replace overloaded operator with function call
|
||||||
|
|||||||
Vendored
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
// "Replace with assignment" "false"
|
// "Replace with assignment (original is empty)" "false"
|
||||||
// ACTION: Replace overloaded operator with function call
|
// ACTION: Replace overloaded operator with function call
|
||||||
// ACTION: Replace with ordinary assignment
|
// ACTION: Replace with ordinary assignment
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
// "Replace with assignment" "false"
|
// "Replace with assignment (original is empty)" "false"
|
||||||
// TOOL: org.jetbrains.kotlin.idea.inspections.SuspiciousCollectionReassignmentInspection
|
// TOOL: org.jetbrains.kotlin.idea.inspections.SuspiciousCollectionReassignmentInspection
|
||||||
// ACTION: Change type to mutable
|
// ACTION: Change type to mutable
|
||||||
// ACTION: Replace overloaded operator with function call
|
// ACTION: Replace overloaded operator with function call
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
// "Replace with assignment" "false"
|
// "Replace with assignment (original is empty)" "false"
|
||||||
// ACTION: Replace overloaded operator with function call
|
// ACTION: Replace overloaded operator with function call
|
||||||
// ACTION: Replace with ordinary assignment
|
// ACTION: Replace with ordinary assignment
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
// "Replace with assignment" "false"
|
// "Replace with assignment (original is empty)" "false"
|
||||||
// TOOL: org.jetbrains.kotlin.idea.inspections.SuspiciousCollectionReassignmentInspection
|
// TOOL: org.jetbrains.kotlin.idea.inspections.SuspiciousCollectionReassignmentInspection
|
||||||
// ACTION: Change type to mutable
|
// ACTION: Change type to mutable
|
||||||
// ACTION: Replace overloaded operator with function call
|
// ACTION: Replace overloaded operator with function call
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
// "Replace with assignment" "false"
|
// "Replace with assignment (original is empty)" "false"
|
||||||
// TOOL: org.jetbrains.kotlin.idea.inspections.SuspiciousCollectionReassignmentInspection
|
// TOOL: org.jetbrains.kotlin.idea.inspections.SuspiciousCollectionReassignmentInspection
|
||||||
// ACTION: Change type to mutable
|
// ACTION: Change type to mutable
|
||||||
// ACTION: Replace overloaded operator with function call
|
// ACTION: Replace overloaded operator with function call
|
||||||
|
|||||||
Vendored
+10
@@ -0,0 +1,10 @@
|
|||||||
|
// "Replace with ordinary assignment" "true"
|
||||||
|
// TOOL: org.jetbrains.kotlin.idea.inspections.SuspiciousCollectionReassignmentInspection
|
||||||
|
// ACTION: Replace overloaded operator with function call
|
||||||
|
// WITH_RUNTIME
|
||||||
|
fun test(otherList: List<Int>, flag: Boolean) {
|
||||||
|
var list = otherList
|
||||||
|
if (flag) {
|
||||||
|
list <caret>+= 4
|
||||||
|
}
|
||||||
|
}
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
// "Replace with ordinary assignment" "true"
|
||||||
|
// TOOL: org.jetbrains.kotlin.idea.inspections.SuspiciousCollectionReassignmentInspection
|
||||||
|
// ACTION: Replace overloaded operator with function call
|
||||||
|
// WITH_RUNTIME
|
||||||
|
fun test(otherList: List<Int>, flag: Boolean) {
|
||||||
|
var list = otherList
|
||||||
|
if (flag) {
|
||||||
|
list = list + 4
|
||||||
|
}
|
||||||
|
}
|
||||||
+13
@@ -4022,6 +4022,19 @@ public class QuickFixMultiFileTestGenerated extends AbstractQuickFixMultiFileTes
|
|||||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/suspiciousCollectionReassignment/replaceWithFilter"), Pattern.compile("^(\\w+)\\.((before\\.Main\\.\\w+)|(test))$"), TargetBackend.ANY, true);
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/suspiciousCollectionReassignment/replaceWithFilter"), Pattern.compile("^(\\w+)\\.((before\\.Main\\.\\w+)|(test))$"), TargetBackend.ANY, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("idea/testData/quickfix/suspiciousCollectionReassignment/replaceWithOrdinaryAssignment")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class ReplaceWithOrdinaryAssignment extends AbstractQuickFixMultiFileTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest(this::doTestWithExtraFile, TargetBackend.ANY, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInReplaceWithOrdinaryAssignment() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/suspiciousCollectionReassignment/replaceWithOrdinaryAssignment"), Pattern.compile("^(\\w+)\\.((before\\.Main\\.\\w+)|(test))$"), TargetBackend.ANY, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("idea/testData/quickfix/toString")
|
@TestMetadata("idea/testData/quickfix/toString")
|
||||||
|
|||||||
@@ -11582,6 +11582,24 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
|
|||||||
runTest("idea/testData/quickfix/suspiciousCollectionReassignment/replaceWithFilter/plusEq.kt");
|
runTest("idea/testData/quickfix/suspiciousCollectionReassignment/replaceWithFilter/plusEq.kt");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("idea/testData/quickfix/suspiciousCollectionReassignment/replaceWithOrdinaryAssignment")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class ReplaceWithOrdinaryAssignment extends AbstractQuickFixTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInReplaceWithOrdinaryAssignment() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/suspiciousCollectionReassignment/replaceWithOrdinaryAssignment"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), TargetBackend.ANY, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("simple.kt")
|
||||||
|
public void testSimple() throws Exception {
|
||||||
|
runTest("idea/testData/quickfix/suspiciousCollectionReassignment/replaceWithOrdinaryAssignment/simple.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("idea/testData/quickfix/toString")
|
@TestMetadata("idea/testData/quickfix/toString")
|
||||||
|
|||||||
Reference in New Issue
Block a user