diff --git a/idea/resources/inspectionDescriptions/UnusedEquals.html b/idea/resources/inspectionDescriptions/UnusedEquals.html new file mode 100644 index 00000000000..dd7a502cd99 --- /dev/null +++ b/idea/resources/inspectionDescriptions/UnusedEquals.html @@ -0,0 +1,5 @@ + + +This inspection reports unused equals expressions. + + diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml index 97564391bd2..bb808b74f7f 100644 --- a/idea/src/META-INF/plugin.xml +++ b/idea/src/META-INF/plugin.xml @@ -2001,6 +2001,15 @@ language="kotlin" /> + + + diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/UnusedEqualsInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/UnusedEqualsInspection.kt new file mode 100644 index 00000000000..39aaddfa483 --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/UnusedEqualsInspection.kt @@ -0,0 +1,50 @@ +/* + * Copyright 2010-2016 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.ProblemHighlightType +import com.intellij.codeInspection.ProblemsHolder +import com.intellij.psi.PsiElementVisitor +import org.jetbrains.kotlin.idea.caches.resolve.analyze +import org.jetbrains.kotlin.lexer.KtTokens +import org.jetbrains.kotlin.psi.KtBinaryExpression +import org.jetbrains.kotlin.psi.KtBlockExpression +import org.jetbrains.kotlin.psi.KtIfExpression +import org.jetbrains.kotlin.psi.KtVisitorVoid +import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsExpression + +class UnusedEqualsInspection : AbstractKotlinInspection() { + + override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor { + return object : KtVisitorVoid() { + override fun visitBinaryExpression(expression: KtBinaryExpression) { + super.visitBinaryExpression(expression) + if (expression.operationToken == KtTokens.EQEQ && + (expression.parent is KtBlockExpression || expression.parent.parent is KtIfExpression)) { + val context = expression.analyze() + if (!expression.isUsedAsExpression(context)) { + holder.registerProblem(expression.operationReference, + "Unused equals expression", + ProblemHighlightType.LIKE_UNUSED_SYMBOL) + + } + } + } + } + } + +} \ No newline at end of file diff --git a/idea/testData/inspections/unusedEquals/inspectionData/expected.xml b/idea/testData/inspections/unusedEquals/inspectionData/expected.xml new file mode 100644 index 00000000000..d676859e2a6 --- /dev/null +++ b/idea/testData/inspections/unusedEquals/inspectionData/expected.xml @@ -0,0 +1,82 @@ + + + test.kt + 4 + light_idea_test_case + + Unused equals expression + Unused equals expression + + + + test.kt + 5 + light_idea_test_case + + Unused equals expression + Unused equals expression + + + + test.kt + 8 + light_idea_test_case + + Unused equals expression + Unused equals expression + + + + test.kt + 13 + light_idea_test_case + + Unused equals expression + Unused equals expression + + + + test.kt + 14 + light_idea_test_case + + Unused equals expression + Unused equals expression + + + + test.kt + 18 + light_idea_test_case + + Unused equals expression + Unused equals expression + + + + test.kt + 38 + light_idea_test_case + + Unused equals expression + Unused equals expression + + + + test.kt + 61 + light_idea_test_case + + Unused equals expression + Unused equals expression + + + + test.kt + 61 + light_idea_test_case + + Unused equals expression + Unused equals expression + + diff --git a/idea/testData/inspections/unusedEquals/inspectionData/inspections.test b/idea/testData/inspections/unusedEquals/inspectionData/inspections.test new file mode 100644 index 00000000000..26e9c541fdf --- /dev/null +++ b/idea/testData/inspections/unusedEquals/inspectionData/inspections.test @@ -0,0 +1 @@ +// INSPECTION_CLASS: org.jetbrains.kotlin.idea.inspections.UnusedEqualsInspection diff --git a/idea/testData/inspections/unusedEquals/test.kt b/idea/testData/inspections/unusedEquals/test.kt new file mode 100644 index 00000000000..96223c803ec --- /dev/null +++ b/idea/testData/inspections/unusedEquals/test.kt @@ -0,0 +1,64 @@ +// WITH_RUNTIME + +fun foo(a: Int, b: Int) { + a == b // not used + a == 1 // not used + + foo2 { + a == b // not used + a == b // used + } + + foo3 { + a == b // not used + a == b // not used + } + + val e = a == b // used + a == b // not used +} + +fun foo2(c: () -> Boolean) { + +} + +fun foo3(d: () -> Unit) { + +} + +fun foo4(a: Int): Boolean { + return a == 1 // used +} + +fun foo5(a: Int) = a == 1 // used + +fun foo6(a: Int) { + foo2 { + fun foo7() { + a == 1 // not used + } + } +} + +fun foo7(a: Int) { + run { + a == b // used as return value of run + } + + if (a == b) return // used +} + +fun foo8(a: Int) { + val eq = if (a > 1) a == 10 else a == -1 // used + + val eq2 = if (a > 1) { + a == 10 // used + } + else { + a == -1 // used + } + + if (a > 1) a == 10 else a == -1 // both unused + + if (a == 10) {} else if (a == -1) {} // both used +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/codeInsight/InspectionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/codeInsight/InspectionTestGenerated.java index e1b3c291bf1..d2d864bfb2b 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/codeInsight/InspectionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/codeInsight/InspectionTestGenerated.java @@ -287,6 +287,12 @@ public class InspectionTestGenerated extends AbstractInspectionTest { doTest(fileName); } + @TestMetadata("unusedEquals/inspectionData/inspections.test") + public void testUnusedEquals_inspectionData_Inspections_test() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspections/unusedEquals/inspectionData/inspections.test"); + doTest(fileName); + } + @TestMetadata("unusedImport/inspectionData/inspections.test") public void testUnusedImport_inspectionData_Inspections_test() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspections/unusedImport/inspectionData/inspections.test");