From 33a93e5fc5f2e8ffc57e73a39cbbc8c38f17a036 Mon Sep 17 00:00:00 2001 From: nd Date: Fri, 7 Jul 2017 16:51:53 +0200 Subject: [PATCH] Inspection detecting redundant Unit return type (#1144) --- .../RedundantUnitReturnType.html | 5 ++ idea/src/META-INF/plugin.xml | 9 ++ .../intentions/RemoveExplicitTypeIntention.kt | 86 +++++++++++++------ .../redundantUnitReturnType/Test.kt | 10 +++ .../inspectionData/expected.xml | 26 ++++++ .../inspectionData/inspections.test | 1 + .../inspectionData/expected.xml | 8 +- .../removeExplicitType/funNoBody.kt | 4 + .../removeExplicitType/funNoBody.kt.after | 4 + .../removeExplicitType/funWithBody.kt | 3 + .../removeExplicitType/funWithBody.kt.after | 3 + .../codeInsight/InspectionTestGenerated.java | 6 ++ .../intentions/IntentionTestGenerated.java | 12 +++ 13 files changed, 147 insertions(+), 30 deletions(-) create mode 100644 idea/resources/inspectionDescriptions/RedundantUnitReturnType.html create mode 100644 idea/testData/inspections/redundantUnitReturnType/Test.kt create mode 100644 idea/testData/inspections/redundantUnitReturnType/inspectionData/expected.xml create mode 100644 idea/testData/inspections/redundantUnitReturnType/inspectionData/inspections.test create mode 100644 idea/testData/intentions/removeExplicitType/funNoBody.kt create mode 100644 idea/testData/intentions/removeExplicitType/funNoBody.kt.after create mode 100644 idea/testData/intentions/removeExplicitType/funWithBody.kt create mode 100644 idea/testData/intentions/removeExplicitType/funWithBody.kt.after diff --git a/idea/resources/inspectionDescriptions/RedundantUnitReturnType.html b/idea/resources/inspectionDescriptions/RedundantUnitReturnType.html new file mode 100644 index 00000000000..5858881304e --- /dev/null +++ b/idea/resources/inspectionDescriptions/RedundantUnitReturnType.html @@ -0,0 +1,5 @@ + + +This inspection reports redundant 'Unit' return type which can be omitted. + + \ No newline at end of file diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml index 63fbccb30d4..ac38b289a26 100644 --- a/idea/src/META-INF/plugin.xml +++ b/idea/src/META-INF/plugin.xml @@ -1977,6 +1977,15 @@ language="kotlin" /> + + ( - RemoveExplicitTypeIntention::class, - { it -> RemoveExplicitTypeIntention.isSetterParameter(it) } -) { - override fun problemHighlightType(element: KtCallableDeclaration) = ProblemHighlightType.LIKE_UNUSED_SYMBOL +class RemoveSetterParameterTypeInspection : AbstractKotlinInspection() { + override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor { + return object : KtVisitorVoid() { + override fun visitDeclaration(dcl: KtDeclaration) { + if (dcl is KtParameter && dcl.typeReference != null && dcl.isSetterParameter) { + holder.registerProblem(dcl, + "Redundant setter parameter type", + ProblemHighlightType.LIKE_UNUSED_SYMBOL, + IntentionWrapper(RemoveExplicitTypeIntention(), dcl.containingKtFile)) + } + } + } + } +} - override fun inspectionTarget(element: KtCallableDeclaration) = (element as? KtParameter)?.typeReference +class RedundantUnitReturnTypeInspection : AbstractKotlinInspection() { + override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor { + return object : KtVisitorVoid() { + override fun visitNamedFunction(function: KtNamedFunction) { + super.visitNamedFunction(function) + if (function.containingFile is KtCodeFragment) return + if ((function.descriptor as? FunctionDescriptor)?.returnType?.isUnit() ?: false) { + function.typeReference?.typeElement?.let { + holder.registerProblem(it, + "Redundant 'Unit' return type", + ProblemHighlightType.LIKE_UNUSED_SYMBOL, + IntentionWrapper(RemoveExplicitTypeIntention(), function.containingKtFile)) + } + } + } + } + } } class RemoveExplicitTypeIntention : SelfTargetingRangeIntention( @@ -39,21 +68,7 @@ class RemoveExplicitTypeIntention : SelfTargetingRangeIntention TextRange(element.startOffset, initializer.startOffset - 1) - element is KtProperty && element.getter != null -> TextRange(element.startOffset, element.typeReference!!.endOffset) - else -> null - } + return getRange(element) } override fun applyTo(element: KtCallableDeclaration, editor: Editor?) { @@ -61,9 +76,28 @@ class RemoveExplicitTypeIntention : SelfTargetingRangeIntention TextRange(element.startOffset, initializer.startOffset - 1) + element is KtProperty && element.getter != null -> TextRange(element.startOffset, element.typeReference!!.endOffset) + element is KtNamedFunction -> TextRange(element.startOffset, element.typeReference!!.endOffset) + else -> null + } + } } } + +private val KtParameter.isSetterParameter: Boolean get() = (parent.parent as? KtPropertyAccessor)?.isSetter ?: false \ No newline at end of file diff --git a/idea/testData/inspections/redundantUnitReturnType/Test.kt b/idea/testData/inspections/redundantUnitReturnType/Test.kt new file mode 100644 index 00000000000..8e51d00f657 --- /dev/null +++ b/idea/testData/inspections/redundantUnitReturnType/Test.kt @@ -0,0 +1,10 @@ +fun foo(): Unit { +} + +fun bar(): Unit { + return Unit +} + +fun baz(): Unit = println("ok") + +fun f1(): Int = 1 \ No newline at end of file diff --git a/idea/testData/inspections/redundantUnitReturnType/inspectionData/expected.xml b/idea/testData/inspections/redundantUnitReturnType/inspectionData/expected.xml new file mode 100644 index 00000000000..7e0d5e77ca5 --- /dev/null +++ b/idea/testData/inspections/redundantUnitReturnType/inspectionData/expected.xml @@ -0,0 +1,26 @@ + + + Test.kt + 1 + light_idea_test_case + + Redundant 'Unit' return type + Redundant Unit return type + + + Test.kt + 4 + light_idea_test_case + + Redundant 'Unit' return type + Redundant Unit return type + + + Test.kt + 8 + light_idea_test_case + + Redundant 'Unit' return type + Redundant Unit return type + + diff --git a/idea/testData/inspections/redundantUnitReturnType/inspectionData/inspections.test b/idea/testData/inspections/redundantUnitReturnType/inspectionData/inspections.test new file mode 100644 index 00000000000..ad41598dff6 --- /dev/null +++ b/idea/testData/inspections/redundantUnitReturnType/inspectionData/inspections.test @@ -0,0 +1 @@ +// INSPECTION_CLASS: org.jetbrains.kotlin.idea.intentions.RedundantUnitReturnTypeInspection \ No newline at end of file diff --git a/idea/testData/inspections/removeSetterParameterType/inspectionData/expected.xml b/idea/testData/inspections/removeSetterParameterType/inspectionData/expected.xml index 185d5689a49..519463a9278 100644 --- a/idea/testData/inspections/removeSetterParameterType/inspectionData/expected.xml +++ b/idea/testData/inspections/removeSetterParameterType/inspectionData/expected.xml @@ -4,15 +4,15 @@ 4 light_idea_test_case - Redundant setter parameter type - Remove explicit type specification + Redundant setter parameter type + Redundant setter parameter type test.kt 10 light_idea_test_case - Redundant setter parameter type - Remove explicit type specification + Redundant setter parameter type + Redundant setter parameter type \ No newline at end of file diff --git a/idea/testData/intentions/removeExplicitType/funNoBody.kt b/idea/testData/intentions/removeExplicitType/funNoBody.kt new file mode 100644 index 00000000000..a0c5c502f9e --- /dev/null +++ b/idea/testData/intentions/removeExplicitType/funNoBody.kt @@ -0,0 +1,4 @@ +fun foo(): Unit = bar() + +fun bar() { +} \ No newline at end of file diff --git a/idea/testData/intentions/removeExplicitType/funNoBody.kt.after b/idea/testData/intentions/removeExplicitType/funNoBody.kt.after new file mode 100644 index 00000000000..d51b1b371e7 --- /dev/null +++ b/idea/testData/intentions/removeExplicitType/funNoBody.kt.after @@ -0,0 +1,4 @@ +fun foo() = bar() + +fun bar() { +} \ No newline at end of file diff --git a/idea/testData/intentions/removeExplicitType/funWithBody.kt b/idea/testData/intentions/removeExplicitType/funWithBody.kt new file mode 100644 index 00000000000..16851d7325c --- /dev/null +++ b/idea/testData/intentions/removeExplicitType/funWithBody.kt @@ -0,0 +1,3 @@ +fun main(args: Array): Unit { + +} \ No newline at end of file diff --git a/idea/testData/intentions/removeExplicitType/funWithBody.kt.after b/idea/testData/intentions/removeExplicitType/funWithBody.kt.after new file mode 100644 index 00000000000..adb5b33c573 --- /dev/null +++ b/idea/testData/intentions/removeExplicitType/funWithBody.kt.after @@ -0,0 +1,3 @@ +fun main(args: Array) { + +} \ 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 1a66544dd51..6fc821ef3aa 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/codeInsight/InspectionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/codeInsight/InspectionTestGenerated.java @@ -281,6 +281,12 @@ public class InspectionTestGenerated extends AbstractInspectionTest { doTest(fileName); } + @TestMetadata("redundantUnitReturnType/inspectionData/inspections.test") + public void testRedundantUnitReturnType_inspectionData_Inspections_test() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspections/redundantUnitReturnType/inspectionData/inspections.test"); + doTest(fileName); + } + @TestMetadata("redundantVisibilityModifier/inspectionData/inspections.test") public void testRedundantVisibilityModifier_inspectionData_Inspections_test() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspections/redundantVisibilityModifier/inspectionData/inspections.test"); diff --git a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java index 18880df5790..c3ca978becd 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java @@ -13010,6 +13010,18 @@ public class IntentionTestGenerated extends AbstractIntentionTest { KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/intentions/removeExplicitType"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), TargetBackend.ANY, true); } + @TestMetadata("funNoBody.kt") + public void testFunNoBody() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/removeExplicitType/funNoBody.kt"); + doTest(fileName); + } + + @TestMetadata("funWithBody.kt") + public void testFunWithBody() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/removeExplicitType/funWithBody.kt"); + doTest(fileName); + } + @TestMetadata("notOnParameterOfFunctionType.kt") public void testNotOnParameterOfFunctionType() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/removeExplicitType/notOnParameterOfFunctionType.kt");