From 204d9e3423d7018ddcd32a0c0efad466e89570d1 Mon Sep 17 00:00:00 2001 From: Toshiaki Kameyama Date: Sun, 22 Oct 2017 19:14:54 +0300 Subject: [PATCH] Introduce inspection detecting self-assignment of properties So #KT-20714 Fixed --- .../SelfAssignment.html | 5 + idea/src/META-INF/plugin.xml | 9 ++ .../inspections/SelfAssignmentInspection.kt | 104 +++++++++++++ .../selfAssignment/.inspection | 1 + .../selfAssignment/applyCorrect.kt | 17 +++ .../selfAssignment/applyIncorrect.kt | 18 +++ .../selfAssignment/applyIncorrect.kt.after | 17 +++ .../selfAssignment/assignToProperty.kt | 11 ++ .../selfAssignment/differentThese.kt | 12 ++ .../selfAssignment/differentThis.kt | 12 ++ .../inspectionsLocal/selfAssignment/list.kt | 7 + .../selfAssignment/localVal.kt | 8 + .../selfAssignment/localVar.kt | 7 + .../selfAssignment/localVar.kt.after | 6 + .../selfAssignment/notAssignment.kt | 6 + .../selfAssignment/notSelf.kt | 12 ++ .../selfAssignment/openProperty.kt | 9 ++ .../selfAssignment/parameter.kt | 7 + .../selfAssignment/property1.kt | 10 ++ .../selfAssignment/property1.kt.after | 9 ++ .../selfAssignment/property2.kt | 10 ++ .../selfAssignment/property2.kt.after | 9 ++ .../selfAssignment/property3.kt | 10 ++ .../selfAssignment/property3.kt.after | 9 ++ .../selfAssignment/propertyHasDelegate.kt | 20 +++ .../selfAssignment/propertyHasGetter.kt | 14 ++ .../selfAssignment/propertyHasSetter.kt | 13 ++ .../selfAssignment/sameThese.kt | 10 ++ .../selfAssignment/sameThese.kt.after | 9 ++ .../selfAssignment/sameThis.kt | 13 ++ .../selfAssignment/sameThis.kt.after | 12 ++ .../inspectionsLocal/selfAssignment/shadow.kt | 5 + .../selfAssignment/withReceiver.kt | 7 + .../LocalInspectionTestGenerated.java | 141 ++++++++++++++++++ 34 files changed, 569 insertions(+) create mode 100644 idea/resources/inspectionDescriptions/SelfAssignment.html create mode 100644 idea/src/org/jetbrains/kotlin/idea/inspections/SelfAssignmentInspection.kt create mode 100644 idea/testData/inspectionsLocal/selfAssignment/.inspection create mode 100644 idea/testData/inspectionsLocal/selfAssignment/applyCorrect.kt create mode 100644 idea/testData/inspectionsLocal/selfAssignment/applyIncorrect.kt create mode 100644 idea/testData/inspectionsLocal/selfAssignment/applyIncorrect.kt.after create mode 100644 idea/testData/inspectionsLocal/selfAssignment/assignToProperty.kt create mode 100644 idea/testData/inspectionsLocal/selfAssignment/differentThese.kt create mode 100644 idea/testData/inspectionsLocal/selfAssignment/differentThis.kt create mode 100644 idea/testData/inspectionsLocal/selfAssignment/list.kt create mode 100644 idea/testData/inspectionsLocal/selfAssignment/localVal.kt create mode 100644 idea/testData/inspectionsLocal/selfAssignment/localVar.kt create mode 100644 idea/testData/inspectionsLocal/selfAssignment/localVar.kt.after create mode 100644 idea/testData/inspectionsLocal/selfAssignment/notAssignment.kt create mode 100644 idea/testData/inspectionsLocal/selfAssignment/notSelf.kt create mode 100644 idea/testData/inspectionsLocal/selfAssignment/openProperty.kt create mode 100644 idea/testData/inspectionsLocal/selfAssignment/parameter.kt create mode 100644 idea/testData/inspectionsLocal/selfAssignment/property1.kt create mode 100644 idea/testData/inspectionsLocal/selfAssignment/property1.kt.after create mode 100644 idea/testData/inspectionsLocal/selfAssignment/property2.kt create mode 100644 idea/testData/inspectionsLocal/selfAssignment/property2.kt.after create mode 100644 idea/testData/inspectionsLocal/selfAssignment/property3.kt create mode 100644 idea/testData/inspectionsLocal/selfAssignment/property3.kt.after create mode 100644 idea/testData/inspectionsLocal/selfAssignment/propertyHasDelegate.kt create mode 100644 idea/testData/inspectionsLocal/selfAssignment/propertyHasGetter.kt create mode 100644 idea/testData/inspectionsLocal/selfAssignment/propertyHasSetter.kt create mode 100644 idea/testData/inspectionsLocal/selfAssignment/sameThese.kt create mode 100644 idea/testData/inspectionsLocal/selfAssignment/sameThese.kt.after create mode 100644 idea/testData/inspectionsLocal/selfAssignment/sameThis.kt create mode 100644 idea/testData/inspectionsLocal/selfAssignment/sameThis.kt.after create mode 100644 idea/testData/inspectionsLocal/selfAssignment/shadow.kt create mode 100644 idea/testData/inspectionsLocal/selfAssignment/withReceiver.kt diff --git a/idea/resources/inspectionDescriptions/SelfAssignment.html b/idea/resources/inspectionDescriptions/SelfAssignment.html new file mode 100644 index 00000000000..d2b4988a838 --- /dev/null +++ b/idea/resources/inspectionDescriptions/SelfAssignment.html @@ -0,0 +1,5 @@ + + +This inspection detects assignments of a variable to itself + + diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml index 795999c9258..8eaad0d039c 100644 --- a/idea/src/META-INF/plugin.xml +++ b/idea/src/META-INF/plugin.xml @@ -2633,6 +2633,15 @@ language="kotlin" /> + + diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/SelfAssignmentInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/SelfAssignmentInspection.kt new file mode 100644 index 00000000000..6d7d680a92a --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/SelfAssignmentInspection.kt @@ -0,0 +1,104 @@ +/* + * 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 + +import com.intellij.codeInspection.* +import com.intellij.openapi.project.Project +import com.intellij.psi.PsiElementVisitor +import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.idea.caches.resolve.analyze +import org.jetbrains.kotlin.lexer.KtTokens +import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.resolve.BindingContext +import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall +import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall +import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode +import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitReceiver + +class SelfAssignmentInspection : AbstractKotlinInspection(), CleanupLocalInspectionTool { + override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean, session: LocalInspectionToolSession): PsiElementVisitor { + return object : KtVisitorVoid() { + + private fun KtExpression.asNameReferenceExpression(): KtNameReferenceExpression? = when (this) { + is KtNameReferenceExpression -> + this + is KtDotQualifiedExpression -> + (selectorExpression as? KtNameReferenceExpression)?.takeIf { receiverExpression is KtThisExpression } + else -> + null + } + + private fun KtExpression.receiverDeclarationDescriptor( + resolvedCall: ResolvedCall, + context: BindingContext + ): DeclarationDescriptor? { + val thisExpression = (this as? KtDotQualifiedExpression)?.receiverExpression as? KtThisExpression + if (thisExpression != null) { + return thisExpression.getResolvedCall(context)?.resultingDescriptor?.containingDeclaration + } + val implicitReceiver = with (resolvedCall) { dispatchReceiver ?: extensionReceiver } as? ImplicitReceiver + return implicitReceiver?.declarationDescriptor + } + + override fun visitBinaryExpression(expression: KtBinaryExpression) { + super.visitBinaryExpression(expression) + + if (expression.operationToken != KtTokens.EQ) return + val left = expression.left + val leftRefExpr = left?.asNameReferenceExpression() ?: return + val right = expression.right + val rightRefExpr = right?.asNameReferenceExpression() ?: return + // To omit analyzing too much + if (leftRefExpr.text != rightRefExpr.text) return + + val context = expression.analyze(BodyResolveMode.PARTIAL) + val leftResolvedCall = left.getResolvedCall(context) + val leftCallee = leftResolvedCall?.resultingDescriptor as? VariableDescriptor ?: return + val rightResolvedCall = right.getResolvedCall(context) + val rightCallee = rightResolvedCall?.resultingDescriptor as? VariableDescriptor ?: return + if (leftCallee != rightCallee) return + + if (!rightCallee.isVar) return + if (rightCallee is PropertyDescriptor) { + if (rightCallee.isOverridable) return + if (rightCallee.accessors.any { !it.isDefault }) return + } + + if (left.receiverDeclarationDescriptor(leftResolvedCall, context) != + right.receiverDeclarationDescriptor(rightResolvedCall, context)) { + return + } + + holder.registerProblem(right, + "Variable '${rightCallee.name}' is assigned to itself", + ProblemHighlightType.GENERIC_ERROR_OR_WARNING, + RemoveSelfAssignmentFix()) + } + } + } +} + +private class RemoveSelfAssignmentFix : LocalQuickFix { + override fun getName() = "Remove self assignment" + + override fun getFamilyName() = name + + override fun applyFix(project: Project, descriptor: ProblemDescriptor) { + val right = descriptor.psiElement as? KtExpression ?: return + right.parent.delete() + } +} diff --git a/idea/testData/inspectionsLocal/selfAssignment/.inspection b/idea/testData/inspectionsLocal/selfAssignment/.inspection new file mode 100644 index 00000000000..244dd9777c8 --- /dev/null +++ b/idea/testData/inspectionsLocal/selfAssignment/.inspection @@ -0,0 +1 @@ +org.jetbrains.kotlin.idea.inspections.SelfAssignmentInspection \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/selfAssignment/applyCorrect.kt b/idea/testData/inspectionsLocal/selfAssignment/applyCorrect.kt new file mode 100644 index 00000000000..44ee6727ef7 --- /dev/null +++ b/idea/testData/inspectionsLocal/selfAssignment/applyCorrect.kt @@ -0,0 +1,17 @@ +// PROBLEM: none +// WITH_RUNTIME + +// Minimized from KT-20714 itself +class ServerUser { + var id = "" + var city = "" + + fun toClientUser() = ClientUser().apply { + id = this@ServerUser.id + city = this@ServerUser.city + } +} + +class ClientUser { + var id = "" +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/selfAssignment/applyIncorrect.kt b/idea/testData/inspectionsLocal/selfAssignment/applyIncorrect.kt new file mode 100644 index 00000000000..1c2573de75b --- /dev/null +++ b/idea/testData/inspectionsLocal/selfAssignment/applyIncorrect.kt @@ -0,0 +1,18 @@ +// PROBLEM: Variable 'city' is assigned to itself +// WITH_RUNTIME +// FIX: Remove self assignment + +// Minimized from KT-20714 itself +class ServerUser { + var id = "" + var city = "" + + fun toClientUser() = ClientUser().apply { + id = this@ServerUser.id + city = this@ServerUser.city + } +} + +class ClientUser { + var id = "" +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/selfAssignment/applyIncorrect.kt.after b/idea/testData/inspectionsLocal/selfAssignment/applyIncorrect.kt.after new file mode 100644 index 00000000000..0953ca3539c --- /dev/null +++ b/idea/testData/inspectionsLocal/selfAssignment/applyIncorrect.kt.after @@ -0,0 +1,17 @@ +// PROBLEM: Variable 'city' is assigned to itself +// WITH_RUNTIME +// FIX: Remove self assignment + +// Minimized from KT-20714 itself +class ServerUser { + var id = "" + var city = "" + + fun toClientUser() = ClientUser().apply { + id = this@ServerUser.id + } +} + +class ClientUser { + var id = "" +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/selfAssignment/assignToProperty.kt b/idea/testData/inspectionsLocal/selfAssignment/assignToProperty.kt new file mode 100644 index 00000000000..25f2be6f42a --- /dev/null +++ b/idea/testData/inspectionsLocal/selfAssignment/assignToProperty.kt @@ -0,0 +1,11 @@ +// PROBLEM: none +// SKIP_ERRORS_BEFORE +// SKIP_ERRORS_AFTER + +class Point { + val x: Int + + constructor(x: Int) { + x = x + } +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/selfAssignment/differentThese.kt b/idea/testData/inspectionsLocal/selfAssignment/differentThese.kt new file mode 100644 index 00000000000..e2530bab3fb --- /dev/null +++ b/idea/testData/inspectionsLocal/selfAssignment/differentThese.kt @@ -0,0 +1,12 @@ +// PROBLEM: none +// WITH_RUNTIME + +class Test { + var foo = 1 + + fun test() { + with (Test()) { + this@Test.foo = this.foo // Different receivers + } + } +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/selfAssignment/differentThis.kt b/idea/testData/inspectionsLocal/selfAssignment/differentThis.kt new file mode 100644 index 00000000000..6af339807bc --- /dev/null +++ b/idea/testData/inspectionsLocal/selfAssignment/differentThis.kt @@ -0,0 +1,12 @@ +// PROBLEM: none +// WITH_RUNTIME + +class Test { + var foo = 1 + + fun test() { + with (Test()) { + this@Test.foo = foo // Different receiver + } + } +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/selfAssignment/list.kt b/idea/testData/inspectionsLocal/selfAssignment/list.kt new file mode 100644 index 00000000000..69045a53947 --- /dev/null +++ b/idea/testData/inspectionsLocal/selfAssignment/list.kt @@ -0,0 +1,7 @@ +// PROBLEM: none +// WITH_RUNTIME + +fun test() { + val list = mutableListOf(1, 2, 3) + list[1] = list[1] +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/selfAssignment/localVal.kt b/idea/testData/inspectionsLocal/selfAssignment/localVal.kt new file mode 100644 index 00000000000..63b7e36482c --- /dev/null +++ b/idea/testData/inspectionsLocal/selfAssignment/localVal.kt @@ -0,0 +1,8 @@ +// PROBLEM: none +// SKIP_ERRORS_BEFORE +// SKIP_ERRORS_AFTER + +fun test() { + val bar = 1 + bar = bar +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/selfAssignment/localVar.kt b/idea/testData/inspectionsLocal/selfAssignment/localVar.kt new file mode 100644 index 00000000000..9ba5e8e4d21 --- /dev/null +++ b/idea/testData/inspectionsLocal/selfAssignment/localVar.kt @@ -0,0 +1,7 @@ +// PROBLEM: Variable 'bar' is assigned to itself +// FIX: Remove self assignment + +fun test() { + var bar = 1 + bar = bar +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/selfAssignment/localVar.kt.after b/idea/testData/inspectionsLocal/selfAssignment/localVar.kt.after new file mode 100644 index 00000000000..947b6b0a8c6 --- /dev/null +++ b/idea/testData/inspectionsLocal/selfAssignment/localVar.kt.after @@ -0,0 +1,6 @@ +// PROBLEM: Variable 'bar' is assigned to itself +// FIX: Remove self assignment + +fun test() { + var bar = 1 +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/selfAssignment/notAssignment.kt b/idea/testData/inspectionsLocal/selfAssignment/notAssignment.kt new file mode 100644 index 00000000000..d03ced27661 --- /dev/null +++ b/idea/testData/inspectionsLocal/selfAssignment/notAssignment.kt @@ -0,0 +1,6 @@ +// PROBLEM: none + +fun test() { + var bar = 1 + bar += bar +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/selfAssignment/notSelf.kt b/idea/testData/inspectionsLocal/selfAssignment/notSelf.kt new file mode 100644 index 00000000000..ed313fec4be --- /dev/null +++ b/idea/testData/inspectionsLocal/selfAssignment/notSelf.kt @@ -0,0 +1,12 @@ +// PROBLEM: none +// WITH_RUNTIME + +class Bar(var foo: Int = 1) + +class Test(var foo: Int = 2) { + fun test() { + Bar().apply { + this.foo = this@Test.foo + } + } +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/selfAssignment/openProperty.kt b/idea/testData/inspectionsLocal/selfAssignment/openProperty.kt new file mode 100644 index 00000000000..fd1e320a739 --- /dev/null +++ b/idea/testData/inspectionsLocal/selfAssignment/openProperty.kt @@ -0,0 +1,9 @@ +// PROBLEM: none + +open class Test { + open var foo = 1 + + fun test() { + foo = this.foo + } +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/selfAssignment/parameter.kt b/idea/testData/inspectionsLocal/selfAssignment/parameter.kt new file mode 100644 index 00000000000..f72d8bc0177 --- /dev/null +++ b/idea/testData/inspectionsLocal/selfAssignment/parameter.kt @@ -0,0 +1,7 @@ +// PROBLEM: none +// SKIP_ERRORS_BEFORE +// SKIP_ERRORS_AFTER + +fun test(bar: Int) { + bar = bar +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/selfAssignment/property1.kt b/idea/testData/inspectionsLocal/selfAssignment/property1.kt new file mode 100644 index 00000000000..8ae46cef95a --- /dev/null +++ b/idea/testData/inspectionsLocal/selfAssignment/property1.kt @@ -0,0 +1,10 @@ +// PROBLEM: Variable 'foo' is assigned to itself +// FIX: Remove self assignment + +class Test { + var foo = 1 + + fun test() { + foo = foo + } +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/selfAssignment/property1.kt.after b/idea/testData/inspectionsLocal/selfAssignment/property1.kt.after new file mode 100644 index 00000000000..f7625bef964 --- /dev/null +++ b/idea/testData/inspectionsLocal/selfAssignment/property1.kt.after @@ -0,0 +1,9 @@ +// PROBLEM: Variable 'foo' is assigned to itself +// FIX: Remove self assignment + +class Test { + var foo = 1 + + fun test() { + } +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/selfAssignment/property2.kt b/idea/testData/inspectionsLocal/selfAssignment/property2.kt new file mode 100644 index 00000000000..53e373d7aa7 --- /dev/null +++ b/idea/testData/inspectionsLocal/selfAssignment/property2.kt @@ -0,0 +1,10 @@ +// PROBLEM: Variable 'foo' is assigned to itself +// FIX: Remove self assignment + +class Test { + var foo = 1 + + fun test() { + foo = this.foo + } +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/selfAssignment/property2.kt.after b/idea/testData/inspectionsLocal/selfAssignment/property2.kt.after new file mode 100644 index 00000000000..f7625bef964 --- /dev/null +++ b/idea/testData/inspectionsLocal/selfAssignment/property2.kt.after @@ -0,0 +1,9 @@ +// PROBLEM: Variable 'foo' is assigned to itself +// FIX: Remove self assignment + +class Test { + var foo = 1 + + fun test() { + } +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/selfAssignment/property3.kt b/idea/testData/inspectionsLocal/selfAssignment/property3.kt new file mode 100644 index 00000000000..e1cf0c274c6 --- /dev/null +++ b/idea/testData/inspectionsLocal/selfAssignment/property3.kt @@ -0,0 +1,10 @@ +// PROBLEM: Variable 'foo' is assigned to itself +// FIX: Remove self assignment + +class Test { + var foo = 1 + + fun test() { + foo = this@Test.foo + } +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/selfAssignment/property3.kt.after b/idea/testData/inspectionsLocal/selfAssignment/property3.kt.after new file mode 100644 index 00000000000..f7625bef964 --- /dev/null +++ b/idea/testData/inspectionsLocal/selfAssignment/property3.kt.after @@ -0,0 +1,9 @@ +// PROBLEM: Variable 'foo' is assigned to itself +// FIX: Remove self assignment + +class Test { + var foo = 1 + + fun test() { + } +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/selfAssignment/propertyHasDelegate.kt b/idea/testData/inspectionsLocal/selfAssignment/propertyHasDelegate.kt new file mode 100644 index 00000000000..dc22e09e6f6 --- /dev/null +++ b/idea/testData/inspectionsLocal/selfAssignment/propertyHasDelegate.kt @@ -0,0 +1,20 @@ +// PROBLEM: none +// WITH_RUNTIME + +import kotlin.properties.ReadWriteProperty +import kotlin.reflect.KProperty + +class Test { + var foo: Int by Delegate() + + fun test() { + foo = foo + } +} + +class Delegate : ReadWriteProperty { + override fun getValue(thisRef: Test, property: KProperty<*>): Int = 1 + override fun setValue(thisRef: Test, property: KProperty<*>, value: Int) { + println() + } +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/selfAssignment/propertyHasGetter.kt b/idea/testData/inspectionsLocal/selfAssignment/propertyHasGetter.kt new file mode 100644 index 00000000000..37c8fdc632c --- /dev/null +++ b/idea/testData/inspectionsLocal/selfAssignment/propertyHasGetter.kt @@ -0,0 +1,14 @@ +// PROBLEM: none +// WITH_RUNTIME + +class Test { + var foo = 1 + get() { + println() + return 2 + } + + fun test() { + foo = foo + } +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/selfAssignment/propertyHasSetter.kt b/idea/testData/inspectionsLocal/selfAssignment/propertyHasSetter.kt new file mode 100644 index 00000000000..7439f26cf60 --- /dev/null +++ b/idea/testData/inspectionsLocal/selfAssignment/propertyHasSetter.kt @@ -0,0 +1,13 @@ +// PROBLEM: none +// WITH_RUNTIME + +class Test { + var foo = 1 + set(value) { + println(value) + } + + fun test() { + foo = foo + } +} diff --git a/idea/testData/inspectionsLocal/selfAssignment/sameThese.kt b/idea/testData/inspectionsLocal/selfAssignment/sameThese.kt new file mode 100644 index 00000000000..299ade0465e --- /dev/null +++ b/idea/testData/inspectionsLocal/selfAssignment/sameThese.kt @@ -0,0 +1,10 @@ +// PROBLEM: Variable 'foo' is assigned to itself +// FIX: Remove self assignment + +class Test { + var foo = 1 + + fun test() { + this.foo = this@Test.foo + } +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/selfAssignment/sameThese.kt.after b/idea/testData/inspectionsLocal/selfAssignment/sameThese.kt.after new file mode 100644 index 00000000000..f7625bef964 --- /dev/null +++ b/idea/testData/inspectionsLocal/selfAssignment/sameThese.kt.after @@ -0,0 +1,9 @@ +// PROBLEM: Variable 'foo' is assigned to itself +// FIX: Remove self assignment + +class Test { + var foo = 1 + + fun test() { + } +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/selfAssignment/sameThis.kt b/idea/testData/inspectionsLocal/selfAssignment/sameThis.kt new file mode 100644 index 00000000000..7f492f1c068 --- /dev/null +++ b/idea/testData/inspectionsLocal/selfAssignment/sameThis.kt @@ -0,0 +1,13 @@ +// PROBLEM: Variable 'foo' is assigned to itself +// WITH_RUNTIME +// FIX: Remove self assignment + +class Test { + var foo = 1 + + fun test() { + with (Test()) { + this.foo = foo + } + } +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/selfAssignment/sameThis.kt.after b/idea/testData/inspectionsLocal/selfAssignment/sameThis.kt.after new file mode 100644 index 00000000000..80eba71f034 --- /dev/null +++ b/idea/testData/inspectionsLocal/selfAssignment/sameThis.kt.after @@ -0,0 +1,12 @@ +// PROBLEM: Variable 'foo' is assigned to itself +// WITH_RUNTIME +// FIX: Remove self assignment + +class Test { + var foo = 1 + + fun test() { + with (Test()) { + } + } +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/selfAssignment/shadow.kt b/idea/testData/inspectionsLocal/selfAssignment/shadow.kt new file mode 100644 index 00000000000..611915bb746 --- /dev/null +++ b/idea/testData/inspectionsLocal/selfAssignment/shadow.kt @@ -0,0 +1,5 @@ +// PROBLEM: none + +fun test(bar: Int) { + var bar = bar +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/selfAssignment/withReceiver.kt b/idea/testData/inspectionsLocal/selfAssignment/withReceiver.kt new file mode 100644 index 00000000000..c4869cfc39e --- /dev/null +++ b/idea/testData/inspectionsLocal/selfAssignment/withReceiver.kt @@ -0,0 +1,7 @@ +// PROBLEM: none + +class Point(var x: Int) { + fun copyFrom(other: Point) { + x = other.x + } +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java index 853c539224a..5bddd35489e 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java @@ -1914,6 +1914,147 @@ public class LocalInspectionTestGenerated extends AbstractLocalInspectionTest { } } + @TestMetadata("idea/testData/inspectionsLocal/selfAssignment") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class SelfAssignment extends AbstractLocalInspectionTest { + public void testAllFilesPresentInSelfAssignment() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/inspectionsLocal/selfAssignment"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), TargetBackend.ANY, true); + } + + @TestMetadata("applyCorrect.kt") + public void testApplyCorrect() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/selfAssignment/applyCorrect.kt"); + doTest(fileName); + } + + @TestMetadata("applyIncorrect.kt") + public void testApplyIncorrect() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/selfAssignment/applyIncorrect.kt"); + doTest(fileName); + } + + @TestMetadata("assignToProperty.kt") + public void testAssignToProperty() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/selfAssignment/assignToProperty.kt"); + doTest(fileName); + } + + @TestMetadata("differentThese.kt") + public void testDifferentThese() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/selfAssignment/differentThese.kt"); + doTest(fileName); + } + + @TestMetadata("differentThis.kt") + public void testDifferentThis() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/selfAssignment/differentThis.kt"); + doTest(fileName); + } + + @TestMetadata("list.kt") + public void testList() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/selfAssignment/list.kt"); + doTest(fileName); + } + + @TestMetadata("localVal.kt") + public void testLocalVal() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/selfAssignment/localVal.kt"); + doTest(fileName); + } + + @TestMetadata("localVar.kt") + public void testLocalVar() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/selfAssignment/localVar.kt"); + doTest(fileName); + } + + @TestMetadata("notAssignment.kt") + public void testNotAssignment() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/selfAssignment/notAssignment.kt"); + doTest(fileName); + } + + @TestMetadata("notSelf.kt") + public void testNotSelf() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/selfAssignment/notSelf.kt"); + doTest(fileName); + } + + @TestMetadata("openProperty.kt") + public void testOpenProperty() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/selfAssignment/openProperty.kt"); + doTest(fileName); + } + + @TestMetadata("parameter.kt") + public void testParameter() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/selfAssignment/parameter.kt"); + doTest(fileName); + } + + @TestMetadata("property1.kt") + public void testProperty1() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/selfAssignment/property1.kt"); + doTest(fileName); + } + + @TestMetadata("property2.kt") + public void testProperty2() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/selfAssignment/property2.kt"); + doTest(fileName); + } + + @TestMetadata("property3.kt") + public void testProperty3() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/selfAssignment/property3.kt"); + doTest(fileName); + } + + @TestMetadata("propertyHasDelegate.kt") + public void testPropertyHasDelegate() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/selfAssignment/propertyHasDelegate.kt"); + doTest(fileName); + } + + @TestMetadata("propertyHasGetter.kt") + public void testPropertyHasGetter() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/selfAssignment/propertyHasGetter.kt"); + doTest(fileName); + } + + @TestMetadata("propertyHasSetter.kt") + public void testPropertyHasSetter() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/selfAssignment/propertyHasSetter.kt"); + doTest(fileName); + } + + @TestMetadata("sameThese.kt") + public void testSameThese() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/selfAssignment/sameThese.kt"); + doTest(fileName); + } + + @TestMetadata("sameThis.kt") + public void testSameThis() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/selfAssignment/sameThis.kt"); + doTest(fileName); + } + + @TestMetadata("shadow.kt") + public void testShadow() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/selfAssignment/shadow.kt"); + doTest(fileName); + } + + @TestMetadata("withReceiver.kt") + public void testWithReceiver() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/selfAssignment/withReceiver.kt"); + doTest(fileName); + } + } + @TestMetadata("idea/testData/inspectionsLocal/unnecessaryVariable") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class)