diff --git a/plugins/kotlin/code-insight/inspections-shared/resources/kotlin.code-insight.inspections.shared.xml b/plugins/kotlin/code-insight/inspections-shared/resources/kotlin.code-insight.inspections.shared.xml index 3f073398e11c..0f481436d1be 100644 --- a/plugins/kotlin/code-insight/inspections-shared/resources/kotlin.code-insight.inspections.shared.xml +++ b/plugins/kotlin/code-insight/inspections-shared/resources/kotlin.code-insight.inspections.shared.xml @@ -97,6 +97,14 @@ language="kotlin" key="inspection.redundant.setter.display.name" bundle="messages.KotlinBundle"/> + + ? { + val newExpression = psiFactory.createExpressionByPattern("$0.$1()", this, name) + val fragment = KtPsiFactory(project).createExpressionCodeFragment(newExpression.text, context) + val expression = fragment.firstChild as? KtExpression ?: return null + return expression.resolveCall()?.successfulFunctionCallOrNull() + } + + context(KtAnalysisSession) + private fun KtForExpression.isSuspendingLoopOrUnresolved(): Boolean { + val loopRangeExpression = loopRange ?: return true + val psiFactory = KtPsiFactory(project) + val iteratorFunction = loopRangeExpression.resolveMemberFunction("iterator", psiFactory) ?: return true + if (iteratorFunction.partiallyAppliedSymbol.symbol.isSuspendSymbol()) { + return true + } + val functionsToCheck = listOf("hasNext", "next") + for (f in functionsToCheck) { + val iteratorExpression = psiFactory.createExpressionByPattern("$0.iterator()", loopRangeExpression) + val resolvedFunction = iteratorExpression.resolveMemberFunction(f, psiFactory, loopRangeExpression) ?: return true + if (resolvedFunction.partiallyAppliedSymbol.symbol.isSuspendSymbol()) { + return true + } + } + return false + } + + context(KtAnalysisSession) + private fun KtCallInfo.isExternalSuspendOrUnresolved(selfSymbol: KtFunctionSymbol): Boolean { + val functionCall = successfulCallOrNull>() ?: return true + val symbol = functionCall.partiallyAppliedSymbol.symbol // Recursive call to itself, ignore + if (symbol == selfSymbol) return false + if (symbol.isSuspendSymbol()) return true + + return if (functionCall is KtCompoundVariableAccessCall) { + val compoundAccessSymbol = functionCall.compoundAccess.operationPartiallyAppliedSymbol.symbol + if (compoundAccessSymbol == selfSymbol) return false + compoundAccessSymbol.isSuspendSymbol() + } else { + false + } + } + + context(KtAnalysisSession) + private fun KtNamedFunction.hasSuspendOrUnresolvedCall(functionSymbol: KtFunctionSymbol): Boolean { + return anyDescendantOfType { expression -> + if (expression == this) return@anyDescendantOfType false + if (expression is KtForExpression) { + return@anyDescendantOfType expression.isSuspendingLoopOrUnresolved() + } + // If resolveCall returns null, we skip it (likely block/function/etc., not an actual expression we want to analyze) + val resolvedCall = expression.resolveCall() + ?: return@anyDescendantOfType false + // If we cannot resolve to anything or a singular call, then we do not know if this might be suspending or not + if (resolvedCall is KtErrorCallInfo) { + return@anyDescendantOfType true + } + resolvedCall.isExternalSuspendOrUnresolved(functionSymbol) + } + } +} \ No newline at end of file diff --git a/plugins/kotlin/code-insight/inspections-shared/tests/k1/test/org/jetbrains/kotlin/idea/codeInsight/inspections/shared/SharedK1InspectionTestGenerated.java b/plugins/kotlin/code-insight/inspections-shared/tests/k1/test/org/jetbrains/kotlin/idea/codeInsight/inspections/shared/SharedK1InspectionTestGenerated.java index fef21e33fbdc..df227fa0cd2b 100644 --- a/plugins/kotlin/code-insight/inspections-shared/tests/k1/test/org/jetbrains/kotlin/idea/codeInsight/inspections/shared/SharedK1InspectionTestGenerated.java +++ b/plugins/kotlin/code-insight/inspections-shared/tests/k1/test/org/jetbrains/kotlin/idea/codeInsight/inspections/shared/SharedK1InspectionTestGenerated.java @@ -229,6 +229,23 @@ public abstract class SharedK1InspectionTestGenerated extends AbstractSharedK1In } } + @RunWith(JUnit3RunnerWithInners.class) + @TestMetadata("../testData/inspections/redundantSuspendModifier") + public abstract static class RedundantSuspendModifier extends AbstractSharedK1InspectionTest { + @RunWith(JUnit3RunnerWithInners.class) + @TestMetadata("../testData/inspections/redundantSuspendModifier/inspectionData") + public static class InspectionData extends AbstractSharedK1InspectionTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); + } + + @TestMetadata("inspections.test") + public void testInspections_test() throws Exception { + runTest("../testData/inspections/redundantSuspendModifier/inspectionData/inspections.test"); + } + } + } + @RunWith(JUnit3RunnerWithInners.class) @TestMetadata("../testData/inspections/removeSetterParameterType") public abstract static class RemoveSetterParameterType extends AbstractSharedK1InspectionTest { diff --git a/plugins/kotlin/code-insight/inspections-shared/tests/k1/test/org/jetbrains/kotlin/idea/codeInsight/inspections/shared/SharedK1LocalInspectionTestGenerated.java b/plugins/kotlin/code-insight/inspections-shared/tests/k1/test/org/jetbrains/kotlin/idea/codeInsight/inspections/shared/SharedK1LocalInspectionTestGenerated.java index ced6f84d3cdd..64ef7cf30227 100644 --- a/plugins/kotlin/code-insight/inspections-shared/tests/k1/test/org/jetbrains/kotlin/idea/codeInsight/inspections/shared/SharedK1LocalInspectionTestGenerated.java +++ b/plugins/kotlin/code-insight/inspections-shared/tests/k1/test/org/jetbrains/kotlin/idea/codeInsight/inspections/shared/SharedK1LocalInspectionTestGenerated.java @@ -987,6 +987,134 @@ public abstract class SharedK1LocalInspectionTestGenerated extends AbstractShare } } + @RunWith(JUnit3RunnerWithInners.class) + @TestMetadata("../testData/inspectionsLocal/redundantSuspend") + public static class RedundantSuspend extends AbstractSharedK1LocalInspectionTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); + } + + @TestMetadata("actual.kt") + public void testActual() throws Exception { + runTest("../testData/inspectionsLocal/redundantSuspend/actual.kt"); + } + + @TestMetadata("coroutineContext.kt") + public void testCoroutineContext() throws Exception { + runTest("../testData/inspectionsLocal/redundantSuspend/coroutineContext.kt"); + } + + @TestMetadata("interface.kt") + public void testInterface() throws Exception { + runTest("../testData/inspectionsLocal/redundantSuspend/interface.kt"); + } + + @TestMetadata("interfaceNoBody.kt") + public void testInterfaceNoBody() throws Exception { + runTest("../testData/inspectionsLocal/redundantSuspend/interfaceNoBody.kt"); + } + + @TestMetadata("invokeOperator.kt") + public void testInvokeOperator() throws Exception { + runTest("../testData/inspectionsLocal/redundantSuspend/invokeOperator.kt"); + } + + @TestMetadata("invokingByQualified.kt") + public void testInvokingByQualified() throws Exception { + runTest("../testData/inspectionsLocal/redundantSuspend/invokingByQualified.kt"); + } + + @TestMetadata("lambdaCall.kt") + public void testLambdaCall() throws Exception { + runTest("../testData/inspectionsLocal/redundantSuspend/lambdaCall.kt"); + } + + @TestMetadata("nonSuspendingLoop.kt") + public void testNonSuspendingLoop() throws Exception { + runTest("../testData/inspectionsLocal/redundantSuspend/nonSuspendingLoop.kt"); + } + + @TestMetadata("nonSuspendingLoopExtensionProperty.kt") + public void testNonSuspendingLoopExtensionProperty() throws Exception { + runTest("../testData/inspectionsLocal/redundantSuspend/nonSuspendingLoopExtensionProperty.kt"); + } + + @TestMetadata("nonSuspendingLoopIteratorOtherClass.kt") + public void testNonSuspendingLoopIteratorOtherClass() throws Exception { + runTest("../testData/inspectionsLocal/redundantSuspend/nonSuspendingLoopIteratorOtherClass.kt"); + } + + @TestMetadata("nonSuspendingLoopLocalExtensionProperty.kt") + public void testNonSuspendingLoopLocalExtensionProperty() throws Exception { + runTest("../testData/inspectionsLocal/redundantSuspend/nonSuspendingLoopLocalExtensionProperty.kt"); + } + + @TestMetadata("nullableFunctionType.kt") + public void testNullableFunctionType() throws Exception { + runTest("../testData/inspectionsLocal/redundantSuspend/nullableFunctionType.kt"); + } + + @TestMetadata("operator.kt") + public void testOperator() throws Exception { + runTest("../testData/inspectionsLocal/redundantSuspend/operator.kt"); + } + + @TestMetadata("operatorAssignment.kt") + public void testOperatorAssignment() throws Exception { + runTest("../testData/inspectionsLocal/redundantSuspend/operatorAssignment.kt"); + } + + @TestMetadata("override.kt") + public void testOverride() throws Exception { + runTest("../testData/inspectionsLocal/redundantSuspend/override.kt"); + } + + @TestMetadata("parenthesized.kt") + public void testParenthesized() throws Exception { + runTest("../testData/inspectionsLocal/redundantSuspend/parenthesized.kt"); + } + + @TestMetadata("recursiveCall.kt") + public void testRecursiveCall() throws Exception { + runTest("../testData/inspectionsLocal/redundantSuspend/recursiveCall.kt"); + } + + @TestMetadata("recursiveOperator.kt") + public void testRecursiveOperator() throws Exception { + runTest("../testData/inspectionsLocal/redundantSuspend/recursiveOperator.kt"); + } + + @TestMetadata("recursiveOperatorAssignment.kt") + public void testRecursiveOperatorAssignment() throws Exception { + runTest("../testData/inspectionsLocal/redundantSuspend/recursiveOperatorAssignment.kt"); + } + + @TestMetadata("selfCallWithDifferentReceiver.kt") + public void testSelfCallWithDifferentReceiver() throws Exception { + runTest("../testData/inspectionsLocal/redundantSuspend/selfCallWithDifferentReceiver.kt"); + } + + @TestMetadata("suspendingLoop.kt") + public void testSuspendingLoop() throws Exception { + runTest("../testData/inspectionsLocal/redundantSuspend/suspendingLoop.kt"); + } + + @TestMetadata("suspendingLoopExtensionProperty.kt") + public void testSuspendingLoopExtensionProperty() throws Exception { + runTest("../testData/inspectionsLocal/redundantSuspend/suspendingLoopExtensionProperty.kt"); + } + + @TestMetadata("suspendingLoopIteratorOtherClass.kt") + public void testSuspendingLoopIteratorOtherClass() throws Exception { + runTest("../testData/inspectionsLocal/redundantSuspend/suspendingLoopIteratorOtherClass.kt"); + } + + @TestMetadata("suspendingLoopLocalExtensionProperty.kt") + public void testSuspendingLoopLocalExtensionProperty() throws Exception { + runTest("../testData/inspectionsLocal/redundantSuspend/suspendingLoopLocalExtensionProperty.kt"); + } + } + @RunWith(JUnit3RunnerWithInners.class) @TestMetadata("../testData/inspectionsLocal/redundantValueArgument") public static class RedundantValueArgument extends AbstractSharedK1LocalInspectionTest { diff --git a/plugins/kotlin/code-insight/inspections-shared/tests/k2/test/org/jetbrains/kotlin/idea/k2/codeInsight/inspections/shared/SharedK2InspectionTestGenerated.java b/plugins/kotlin/code-insight/inspections-shared/tests/k2/test/org/jetbrains/kotlin/idea/k2/codeInsight/inspections/shared/SharedK2InspectionTestGenerated.java index d8b4607ce728..c5a0071c5798 100644 --- a/plugins/kotlin/code-insight/inspections-shared/tests/k2/test/org/jetbrains/kotlin/idea/k2/codeInsight/inspections/shared/SharedK2InspectionTestGenerated.java +++ b/plugins/kotlin/code-insight/inspections-shared/tests/k2/test/org/jetbrains/kotlin/idea/k2/codeInsight/inspections/shared/SharedK2InspectionTestGenerated.java @@ -229,6 +229,23 @@ public abstract class SharedK2InspectionTestGenerated extends AbstractSharedK2In } } + @RunWith(JUnit3RunnerWithInners.class) + @TestMetadata("../testData/inspections/redundantSuspendModifier") + public abstract static class RedundantSuspendModifier extends AbstractSharedK2InspectionTest { + @RunWith(JUnit3RunnerWithInners.class) + @TestMetadata("../testData/inspections/redundantSuspendModifier/inspectionData") + public static class InspectionData extends AbstractSharedK2InspectionTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); + } + + @TestMetadata("inspections.test") + public void testInspections_test() throws Exception { + runTest("../testData/inspections/redundantSuspendModifier/inspectionData/inspections.test"); + } + } + } + @RunWith(JUnit3RunnerWithInners.class) @TestMetadata("../testData/inspections/removeSetterParameterType") public abstract static class RemoveSetterParameterType extends AbstractSharedK2InspectionTest { diff --git a/plugins/kotlin/code-insight/inspections-shared/tests/k2/test/org/jetbrains/kotlin/idea/k2/codeInsight/inspections/shared/SharedK2LocalInspectionTestGenerated.java b/plugins/kotlin/code-insight/inspections-shared/tests/k2/test/org/jetbrains/kotlin/idea/k2/codeInsight/inspections/shared/SharedK2LocalInspectionTestGenerated.java index 954f2c66be62..4a157dde1092 100644 --- a/plugins/kotlin/code-insight/inspections-shared/tests/k2/test/org/jetbrains/kotlin/idea/k2/codeInsight/inspections/shared/SharedK2LocalInspectionTestGenerated.java +++ b/plugins/kotlin/code-insight/inspections-shared/tests/k2/test/org/jetbrains/kotlin/idea/k2/codeInsight/inspections/shared/SharedK2LocalInspectionTestGenerated.java @@ -987,6 +987,134 @@ public abstract class SharedK2LocalInspectionTestGenerated extends AbstractShare } } + @RunWith(JUnit3RunnerWithInners.class) + @TestMetadata("../testData/inspectionsLocal/redundantSuspend") + public static class RedundantSuspend extends AbstractSharedK2LocalInspectionTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); + } + + @TestMetadata("actual.kt") + public void testActual() throws Exception { + runTest("../testData/inspectionsLocal/redundantSuspend/actual.kt"); + } + + @TestMetadata("coroutineContext.kt") + public void testCoroutineContext() throws Exception { + runTest("../testData/inspectionsLocal/redundantSuspend/coroutineContext.kt"); + } + + @TestMetadata("interface.kt") + public void testInterface() throws Exception { + runTest("../testData/inspectionsLocal/redundantSuspend/interface.kt"); + } + + @TestMetadata("interfaceNoBody.kt") + public void testInterfaceNoBody() throws Exception { + runTest("../testData/inspectionsLocal/redundantSuspend/interfaceNoBody.kt"); + } + + @TestMetadata("invokeOperator.kt") + public void testInvokeOperator() throws Exception { + runTest("../testData/inspectionsLocal/redundantSuspend/invokeOperator.kt"); + } + + @TestMetadata("invokingByQualified.kt") + public void testInvokingByQualified() throws Exception { + runTest("../testData/inspectionsLocal/redundantSuspend/invokingByQualified.kt"); + } + + @TestMetadata("lambdaCall.kt") + public void testLambdaCall() throws Exception { + runTest("../testData/inspectionsLocal/redundantSuspend/lambdaCall.kt"); + } + + @TestMetadata("nonSuspendingLoop.kt") + public void testNonSuspendingLoop() throws Exception { + runTest("../testData/inspectionsLocal/redundantSuspend/nonSuspendingLoop.kt"); + } + + @TestMetadata("nonSuspendingLoopExtensionProperty.kt") + public void testNonSuspendingLoopExtensionProperty() throws Exception { + runTest("../testData/inspectionsLocal/redundantSuspend/nonSuspendingLoopExtensionProperty.kt"); + } + + @TestMetadata("nonSuspendingLoopIteratorOtherClass.kt") + public void testNonSuspendingLoopIteratorOtherClass() throws Exception { + runTest("../testData/inspectionsLocal/redundantSuspend/nonSuspendingLoopIteratorOtherClass.kt"); + } + + @TestMetadata("nonSuspendingLoopLocalExtensionProperty.kt") + public void testNonSuspendingLoopLocalExtensionProperty() throws Exception { + runTest("../testData/inspectionsLocal/redundantSuspend/nonSuspendingLoopLocalExtensionProperty.kt"); + } + + @TestMetadata("nullableFunctionType.kt") + public void testNullableFunctionType() throws Exception { + runTest("../testData/inspectionsLocal/redundantSuspend/nullableFunctionType.kt"); + } + + @TestMetadata("operator.kt") + public void testOperator() throws Exception { + runTest("../testData/inspectionsLocal/redundantSuspend/operator.kt"); + } + + @TestMetadata("operatorAssignment.kt") + public void testOperatorAssignment() throws Exception { + runTest("../testData/inspectionsLocal/redundantSuspend/operatorAssignment.kt"); + } + + @TestMetadata("override.kt") + public void testOverride() throws Exception { + runTest("../testData/inspectionsLocal/redundantSuspend/override.kt"); + } + + @TestMetadata("parenthesized.kt") + public void testParenthesized() throws Exception { + runTest("../testData/inspectionsLocal/redundantSuspend/parenthesized.kt"); + } + + @TestMetadata("recursiveCall.kt") + public void testRecursiveCall() throws Exception { + runTest("../testData/inspectionsLocal/redundantSuspend/recursiveCall.kt"); + } + + @TestMetadata("recursiveOperator.kt") + public void testRecursiveOperator() throws Exception { + runTest("../testData/inspectionsLocal/redundantSuspend/recursiveOperator.kt"); + } + + @TestMetadata("recursiveOperatorAssignment.kt") + public void testRecursiveOperatorAssignment() throws Exception { + runTest("../testData/inspectionsLocal/redundantSuspend/recursiveOperatorAssignment.kt"); + } + + @TestMetadata("selfCallWithDifferentReceiver.kt") + public void testSelfCallWithDifferentReceiver() throws Exception { + runTest("../testData/inspectionsLocal/redundantSuspend/selfCallWithDifferentReceiver.kt"); + } + + @TestMetadata("suspendingLoop.kt") + public void testSuspendingLoop() throws Exception { + runTest("../testData/inspectionsLocal/redundantSuspend/suspendingLoop.kt"); + } + + @TestMetadata("suspendingLoopExtensionProperty.kt") + public void testSuspendingLoopExtensionProperty() throws Exception { + runTest("../testData/inspectionsLocal/redundantSuspend/suspendingLoopExtensionProperty.kt"); + } + + @TestMetadata("suspendingLoopIteratorOtherClass.kt") + public void testSuspendingLoopIteratorOtherClass() throws Exception { + runTest("../testData/inspectionsLocal/redundantSuspend/suspendingLoopIteratorOtherClass.kt"); + } + + @TestMetadata("suspendingLoopLocalExtensionProperty.kt") + public void testSuspendingLoopLocalExtensionProperty() throws Exception { + runTest("../testData/inspectionsLocal/redundantSuspend/suspendingLoopLocalExtensionProperty.kt"); + } + } + @RunWith(JUnit3RunnerWithInners.class) @TestMetadata("../testData/inspectionsLocal/redundantValueArgument") public static class RedundantValueArgument extends AbstractSharedK2LocalInspectionTest { diff --git a/plugins/kotlin/idea/tests/testData/inspections/redundantSuspendModifier/inspectionData/expected.xml b/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspections/redundantSuspendModifier/inspectionData/expected.xml similarity index 100% rename from plugins/kotlin/idea/tests/testData/inspections/redundantSuspendModifier/inspectionData/expected.xml rename to plugins/kotlin/code-insight/inspections-shared/tests/testData/inspections/redundantSuspendModifier/inspectionData/expected.xml diff --git a/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspections/redundantSuspendModifier/inspectionData/inspections.test b/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspections/redundantSuspendModifier/inspectionData/inspections.test new file mode 100644 index 000000000000..3ecd4c147804 --- /dev/null +++ b/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspections/redundantSuspendModifier/inspectionData/inspections.test @@ -0,0 +1,2 @@ +// INSPECTION_CLASS: org.jetbrains.kotlin.idea.codeInsight.inspections.shared.RedundantSuspendModifierInspection +// K2_INSPECTION_CLASS: org.jetbrains.kotlin.idea.codeInsight.inspections.shared.RedundantSuspendModifierInspection diff --git a/plugins/kotlin/idea/tests/testData/inspections/redundantSuspendModifier/operators.kt b/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspections/redundantSuspendModifier/operators.kt similarity index 100% rename from plugins/kotlin/idea/tests/testData/inspections/redundantSuspendModifier/operators.kt rename to plugins/kotlin/code-insight/inspections-shared/tests/testData/inspections/redundantSuspendModifier/operators.kt diff --git a/plugins/kotlin/idea/tests/testData/inspections/redundantSuspendModifier/test.kt b/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspections/redundantSuspendModifier/test.kt similarity index 100% rename from plugins/kotlin/idea/tests/testData/inspections/redundantSuspendModifier/test.kt rename to plugins/kotlin/code-insight/inspections-shared/tests/testData/inspections/redundantSuspendModifier/test.kt diff --git a/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/.inspection b/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/.inspection new file mode 100644 index 000000000000..8ff5c3987ad6 --- /dev/null +++ b/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/.inspection @@ -0,0 +1 @@ +org.jetbrains.kotlin.idea.codeInsight.inspections.shared.RedundantSuspendModifierInspection \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/redundantSuspend/actual.kt b/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/actual.kt similarity index 100% rename from plugins/kotlin/idea/tests/testData/inspectionsLocal/redundantSuspend/actual.kt rename to plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/actual.kt diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/redundantSuspend/coroutineContext.kt b/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/coroutineContext.kt similarity index 100% rename from plugins/kotlin/idea/tests/testData/inspectionsLocal/redundantSuspend/coroutineContext.kt rename to plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/coroutineContext.kt diff --git a/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/interface.kt b/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/interface.kt new file mode 100644 index 000000000000..62e2e66ea46e --- /dev/null +++ b/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/interface.kt @@ -0,0 +1,7 @@ +// PROBLEM: none + +interface Suspended { + suspend fun bar() { + + } +} \ No newline at end of file diff --git a/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/interfaceNoBody.kt b/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/interfaceNoBody.kt new file mode 100644 index 000000000000..c71ad9e9dffa --- /dev/null +++ b/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/interfaceNoBody.kt @@ -0,0 +1,6 @@ +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +// PROBLEM: none + +interface Suspended { + suspend fun bar() +} \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/redundantSuspend/invokeOperator.kt b/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/invokeOperator.kt similarity index 100% rename from plugins/kotlin/idea/tests/testData/inspectionsLocal/redundantSuspend/invokeOperator.kt rename to plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/invokeOperator.kt diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/redundantSuspend/invokingByQualified.kt b/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/invokingByQualified.kt similarity index 100% rename from plugins/kotlin/idea/tests/testData/inspectionsLocal/redundantSuspend/invokingByQualified.kt rename to plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/invokingByQualified.kt diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/redundantSuspend/lambdaCall.kt b/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/lambdaCall.kt similarity index 100% rename from plugins/kotlin/idea/tests/testData/inspectionsLocal/redundantSuspend/lambdaCall.kt rename to plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/lambdaCall.kt diff --git a/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/nonSuspendingLoop.kt b/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/nonSuspendingLoop.kt new file mode 100644 index 000000000000..45a90b76dada --- /dev/null +++ b/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/nonSuspendingLoop.kt @@ -0,0 +1,11 @@ +class Iterable { + operator fun iterator() = this + operator fun hasNext(): Boolean = false + operator fun next(): Int = 0 +} + +suspend fun foo() { + val iterable = Iterable() + for (x in iterable) { + } +} \ No newline at end of file diff --git a/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/nonSuspendingLoop.kt.after b/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/nonSuspendingLoop.kt.after new file mode 100644 index 000000000000..d61eb718f82e --- /dev/null +++ b/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/nonSuspendingLoop.kt.after @@ -0,0 +1,11 @@ +class Iterable { + operator fun iterator() = this + operator fun hasNext(): Boolean = false + operator fun next(): Int = 0 +} + +fun foo() { + val iterable = Iterable() + for (x in iterable) { + } +} \ No newline at end of file diff --git a/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/nonSuspendingLoopExtensionProperty.kt b/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/nonSuspendingLoopExtensionProperty.kt new file mode 100644 index 000000000000..82278465357d --- /dev/null +++ b/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/nonSuspendingLoopExtensionProperty.kt @@ -0,0 +1,12 @@ +class SIterable { +} + +operator fun SIterable.iterator() = this +operator fun SIterable.hasNext(): Boolean = false +operator fun SIterable.next(): Int = 0 + +suspend fun foo() { + val iterable = SIterable() + for (x in iterable) { + } +} \ No newline at end of file diff --git a/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/nonSuspendingLoopExtensionProperty.kt.after b/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/nonSuspendingLoopExtensionProperty.kt.after new file mode 100644 index 000000000000..7f2521f30564 --- /dev/null +++ b/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/nonSuspendingLoopExtensionProperty.kt.after @@ -0,0 +1,12 @@ +class SIterable { +} + +operator fun SIterable.iterator() = this +operator fun SIterable.hasNext(): Boolean = false +operator fun SIterable.next(): Int = 0 + +fun foo() { + val iterable = SIterable() + for (x in iterable) { + } +} \ No newline at end of file diff --git a/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/nonSuspendingLoopIteratorOtherClass.kt b/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/nonSuspendingLoopIteratorOtherClass.kt new file mode 100644 index 000000000000..a913e8f7e392 --- /dev/null +++ b/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/nonSuspendingLoopIteratorOtherClass.kt @@ -0,0 +1,14 @@ +class OtherIterator { + operator fun hasNext(): Boolean = false + operator fun next(): Int = 0 +} + +class SIterable { + operator fun iterator() = OtherIterator() +} + +suspend fun foo() { + val iterable = SIterable() + for (x in iterable) { + } +} \ No newline at end of file diff --git a/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/nonSuspendingLoopIteratorOtherClass.kt.after b/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/nonSuspendingLoopIteratorOtherClass.kt.after new file mode 100644 index 000000000000..2252c2d902c1 --- /dev/null +++ b/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/nonSuspendingLoopIteratorOtherClass.kt.after @@ -0,0 +1,14 @@ +class OtherIterator { + operator fun hasNext(): Boolean = false + operator fun next(): Int = 0 +} + +class SIterable { + operator fun iterator() = OtherIterator() +} + +fun foo() { + val iterable = SIterable() + for (x in iterable) { + } +} \ No newline at end of file diff --git a/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/nonSuspendingLoopLocalExtensionProperty.kt b/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/nonSuspendingLoopLocalExtensionProperty.kt new file mode 100644 index 000000000000..c6e70926772e --- /dev/null +++ b/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/nonSuspendingLoopLocalExtensionProperty.kt @@ -0,0 +1,12 @@ +class SIterable { +} + +suspend fun foo() { + operator fun SIterable.iterator() = this + operator fun SIterable.hasNext(): Boolean = false + operator fun SIterable.next(): Int = 0 + + val iterable = SIterable() + for (x in iterable) { + } +} \ No newline at end of file diff --git a/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/nonSuspendingLoopLocalExtensionProperty.kt.after b/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/nonSuspendingLoopLocalExtensionProperty.kt.after new file mode 100644 index 000000000000..54adf890cc56 --- /dev/null +++ b/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/nonSuspendingLoopLocalExtensionProperty.kt.after @@ -0,0 +1,12 @@ +class SIterable { +} + +fun foo() { + operator fun SIterable.iterator() = this + operator fun SIterable.hasNext(): Boolean = false + operator fun SIterable.next(): Int = 0 + + val iterable = SIterable() + for (x in iterable) { + } +} \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/redundantSuspend/nullableFunctionType.kt b/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/nullableFunctionType.kt similarity index 100% rename from plugins/kotlin/idea/tests/testData/inspectionsLocal/redundantSuspend/nullableFunctionType.kt rename to plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/nullableFunctionType.kt diff --git a/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/operator.kt b/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/operator.kt new file mode 100644 index 000000000000..c0471f7f03b4 --- /dev/null +++ b/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/operator.kt @@ -0,0 +1,9 @@ +// PROBLEM: none + +class A(val x: Int) { + suspend operator fun plus(a: A): A = A(1) +} + +suspend fun foo(a1: A, a2: A): A { + return a1 + a2 +} \ No newline at end of file diff --git a/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/operatorAssignment.kt b/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/operatorAssignment.kt new file mode 100644 index 000000000000..ba3e10a51233 --- /dev/null +++ b/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/operatorAssignment.kt @@ -0,0 +1,10 @@ +// PROBLEM: none + +class A(val x: Int) { + suspend operator fun plus(a: A): A = A(1) +} + +suspend fun foo(a1: A, a2: A) { + var a = a1 + a += a2 +} \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/redundantSuspend/override.kt b/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/override.kt similarity index 100% rename from plugins/kotlin/idea/tests/testData/inspectionsLocal/redundantSuspend/override.kt rename to plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/override.kt diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/redundantSuspend/parenthesized.kt b/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/parenthesized.kt similarity index 100% rename from plugins/kotlin/idea/tests/testData/inspectionsLocal/redundantSuspend/parenthesized.kt rename to plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/parenthesized.kt diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/redundantSuspend/recursiveCall.kt b/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/recursiveCall.kt similarity index 100% rename from plugins/kotlin/idea/tests/testData/inspectionsLocal/redundantSuspend/recursiveCall.kt rename to plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/recursiveCall.kt diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/redundantSuspend/recursiveCall.kt.after b/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/recursiveCall.kt.after similarity index 100% rename from plugins/kotlin/idea/tests/testData/inspectionsLocal/redundantSuspend/recursiveCall.kt.after rename to plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/recursiveCall.kt.after diff --git a/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/recursiveOperator.kt b/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/recursiveOperator.kt new file mode 100644 index 000000000000..ddac84bb01a4 --- /dev/null +++ b/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/recursiveOperator.kt @@ -0,0 +1,5 @@ +class A(val x: Int) { + suspend operator fun plus(a: A): A { + return a + a + } +} \ No newline at end of file diff --git a/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/recursiveOperator.kt.after b/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/recursiveOperator.kt.after new file mode 100644 index 000000000000..921644f6ca2d --- /dev/null +++ b/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/recursiveOperator.kt.after @@ -0,0 +1,5 @@ +class A(val x: Int) { + operator fun plus(a: A): A { + return a + a + } +} \ No newline at end of file diff --git a/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/recursiveOperatorAssignment.kt b/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/recursiveOperatorAssignment.kt new file mode 100644 index 000000000000..850ced8ff117 --- /dev/null +++ b/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/recursiveOperatorAssignment.kt @@ -0,0 +1,7 @@ +class A(val x: Int) { + suspend operator fun plus(a: A): A { + var a = a + a += a + return a + } +} \ No newline at end of file diff --git a/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/recursiveOperatorAssignment.kt.after b/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/recursiveOperatorAssignment.kt.after new file mode 100644 index 000000000000..2db3b890d9e7 --- /dev/null +++ b/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/recursiveOperatorAssignment.kt.after @@ -0,0 +1,7 @@ +class A(val x: Int) { + operator fun plus(a: A): A { + var a = a + a += a + return a + } +} \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/redundantSuspend/selfCallWithDifferentReceiver.kt b/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/selfCallWithDifferentReceiver.kt similarity index 100% rename from plugins/kotlin/idea/tests/testData/inspectionsLocal/redundantSuspend/selfCallWithDifferentReceiver.kt rename to plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/selfCallWithDifferentReceiver.kt diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/redundantSuspend/selfCallWithDifferentReceiver.kt.after b/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/selfCallWithDifferentReceiver.kt.after similarity index 100% rename from plugins/kotlin/idea/tests/testData/inspectionsLocal/redundantSuspend/selfCallWithDifferentReceiver.kt.after rename to plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/selfCallWithDifferentReceiver.kt.after diff --git a/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/suspendingLoop.kt b/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/suspendingLoop.kt new file mode 100644 index 000000000000..6d6fe0e4faf0 --- /dev/null +++ b/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/suspendingLoop.kt @@ -0,0 +1,13 @@ +// PROBLEM: none + +class SIterable { + operator fun iterator() = this + suspend operator fun hasNext(): Boolean = false + suspend operator fun next(): Int = 0 +} + +suspend fun foo() { + val iterable = SIterable() + for (x in iterable) { + } +} \ No newline at end of file diff --git a/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/suspendingLoopExtensionProperty.kt b/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/suspendingLoopExtensionProperty.kt new file mode 100644 index 000000000000..041d893b63aa --- /dev/null +++ b/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/suspendingLoopExtensionProperty.kt @@ -0,0 +1,15 @@ +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +// PROBLEM: none + +class SIterable { +} + +operator fun SIterable.iterator() = this +suspend operator fun SIterable.hasNext(): Boolean = false +suspend operator fun SIterable.next(): Int = 0 + +suspend fun foo() { + val iterable = SIterable() + for (x in iterable) { + } +} \ No newline at end of file diff --git a/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/suspendingLoopIteratorOtherClass.kt b/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/suspendingLoopIteratorOtherClass.kt new file mode 100644 index 000000000000..7081c75db56a --- /dev/null +++ b/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/suspendingLoopIteratorOtherClass.kt @@ -0,0 +1,17 @@ +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +// PROBLEM: none + +class OtherIterator { + suspend operator fun hasNext(): Boolean = false + suspend operator fun next(): Int = 0 +} + +class SIterable { + operator fun iterator() = OtherIterator() +} + +suspend fun foo() { + val iterable = SIterable() + for (x in iterable) { + } +} \ No newline at end of file diff --git a/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/suspendingLoopLocalExtensionProperty.kt b/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/suspendingLoopLocalExtensionProperty.kt new file mode 100644 index 000000000000..ab4dc507033e --- /dev/null +++ b/plugins/kotlin/code-insight/inspections-shared/tests/testData/inspectionsLocal/redundantSuspend/suspendingLoopLocalExtensionProperty.kt @@ -0,0 +1,15 @@ +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +// PROBLEM: none + +class SIterable { +} + +suspend fun foo() { + operator fun SIterable.iterator() = this + suspend operator fun SIterable.hasNext(): Boolean = false + suspend operator fun SIterable.next(): Int = 0 + + val iterable = SIterable() + for (x in iterable) { + } +} \ No newline at end of file diff --git a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/inspections/RedundantSuspendModifierInspection.kt b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/inspections/RedundantSuspendModifierInspection.kt deleted file mode 100644 index b3810c037351..000000000000 --- a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/inspections/RedundantSuspendModifierInspection.kt +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. - -package org.jetbrains.kotlin.idea.inspections - -import com.intellij.codeInspection.IntentionWrapper -import com.intellij.codeInspection.LocalInspectionToolSession -import com.intellij.codeInspection.ProblemsHolder -import com.intellij.psi.PsiElementVisitor -import org.jetbrains.kotlin.config.LanguageFeature -import org.jetbrains.kotlin.descriptors.Modality -import org.jetbrains.kotlin.diagnostics.Errors -import org.jetbrains.kotlin.idea.base.resources.KotlinBundle -import org.jetbrains.kotlin.idea.base.projectStructure.languageVersionSettings -import org.jetbrains.kotlin.idea.caches.resolve.analyzeWithContent -import org.jetbrains.kotlin.idea.highlighter.SuspendCallKind -import org.jetbrains.kotlin.idea.highlighter.getSuspendCallKind -import org.jetbrains.kotlin.idea.quickfix.RemoveModifierFixBase -import org.jetbrains.kotlin.lexer.KtTokens -import org.jetbrains.kotlin.psi.KtExpression -import org.jetbrains.kotlin.psi.KtNamedFunction -import org.jetbrains.kotlin.psi.namedFunctionVisitor -import org.jetbrains.kotlin.psi.psiUtil.anyDescendantOfType -import org.jetbrains.kotlin.psi.psiUtil.isAncestor -import org.jetbrains.kotlin.resolve.BindingContext -import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall -import org.jetbrains.kotlin.resolve.calls.util.getResolvedCall - -import org.jetbrains.kotlin.idea.codeinsight.api.classic.inspections.AbstractKotlinInspection - -class RedundantSuspendModifierInspection : AbstractKotlinInspection() { - override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean, session: LocalInspectionToolSession): PsiElementVisitor { - return namedFunctionVisitor(fun(function) { - if (!function.languageVersionSettings.supportsFeature(LanguageFeature.Coroutines)) return - - val suspendModifier = function.modifierList?.getModifier(KtTokens.SUSPEND_KEYWORD) ?: return - if (!function.hasBody()) return - if (function.hasModifier(KtTokens.OVERRIDE_KEYWORD) || function.hasModifier(KtTokens.ACTUAL_KEYWORD)) return - - val context = function.analyzeWithContent() - val descriptor = context[BindingContext.FUNCTION, function] ?: return - if (descriptor.modality == Modality.OPEN) return - - if (function.hasSuspendCalls(context)) return - - if (function.hasAnyUnresolvedCalls(context)) return - - holder.registerProblem( - suspendModifier, - KotlinBundle.message("redundant.suspend.modifier"), - IntentionWrapper(RemoveModifierFixBase(function, KtTokens.SUSPEND_KEYWORD, isRedundant = true).asIntention()) - ) - }) - } - - private fun KtNamedFunction.hasAnyUnresolvedCalls(context: BindingContext): Boolean { - return context.diagnostics.any { - it.factory == Errors.UNRESOLVED_REFERENCE && this.isAncestor(it.psiElement) - } - } - - private fun KtNamedFunction.hasSuspendCalls(bindingContext: BindingContext): Boolean { - val selfDescriptor = bindingContext[BindingContext.DECLARATION_TO_DESCRIPTOR, this] ?: return false - - return anyDescendantOfType { expression -> - val kind = getSuspendCallKind(expression, bindingContext) ?: return@anyDescendantOfType false - if (kind is SuspendCallKind.FunctionCall) { - val resolvedCall = kind.element.getResolvedCall(bindingContext) - if (resolvedCall != null) { - val isSelfCall = when (resolvedCall) { - is VariableAsFunctionResolvedCall -> selfDescriptor == resolvedCall.functionCall.candidateDescriptor.original - else -> selfDescriptor == resolvedCall.candidateDescriptor.original - } - - if (isSelfCall) { - return@anyDescendantOfType false - } - } - } - - return@anyDescendantOfType true - } - } -} diff --git a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/inspections/InspectionTestGenerated.java b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/inspections/InspectionTestGenerated.java index 85eb709c477e..79fd7b344b29 100644 --- a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/inspections/InspectionTestGenerated.java +++ b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/inspections/InspectionTestGenerated.java @@ -273,11 +273,6 @@ public abstract class InspectionTestGenerated extends AbstractInspectionTest { runTest("testData/inspections/redundantSamConstructor/inspectionData/inspections.test"); } - @TestMetadata("redundantSuspendModifier/inspectionData/inspections.test") - public void testRedundantSuspendModifier_inspectionData_Inspections_test() throws Exception { - runTest("testData/inspections/redundantSuspendModifier/inspectionData/inspections.test"); - } - @TestMetadata("redundantUnitReturnType/inspectionData/inspections.test") public void testRedundantUnitReturnType_inspectionData_Inspections_test() throws Exception { runTest("testData/inspections/redundantUnitReturnType/inspectionData/inspections.test"); diff --git a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java index 6b7d4bcebcd4..1ec441e8c3df 100644 --- a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java +++ b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java @@ -10492,64 +10492,6 @@ public abstract class LocalInspectionTestGenerated extends AbstractLocalInspecti } } - @RunWith(JUnit3RunnerWithInners.class) - @TestMetadata("testData/inspectionsLocal/redundantSuspend") - public static class RedundantSuspend extends AbstractLocalInspectionTest { - private void runTest(String testDataFilePath) throws Exception { - KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); - } - - @TestMetadata("actual.kt") - public void testActual() throws Exception { - runTest("testData/inspectionsLocal/redundantSuspend/actual.kt"); - } - - @TestMetadata("coroutineContext.kt") - public void testCoroutineContext() throws Exception { - runTest("testData/inspectionsLocal/redundantSuspend/coroutineContext.kt"); - } - - @TestMetadata("invokeOperator.kt") - public void testInvokeOperator() throws Exception { - runTest("testData/inspectionsLocal/redundantSuspend/invokeOperator.kt"); - } - - @TestMetadata("invokingByQualified.kt") - public void testInvokingByQualified() throws Exception { - runTest("testData/inspectionsLocal/redundantSuspend/invokingByQualified.kt"); - } - - @TestMetadata("lambdaCall.kt") - public void testLambdaCall() throws Exception { - runTest("testData/inspectionsLocal/redundantSuspend/lambdaCall.kt"); - } - - @TestMetadata("nullableFunctionType.kt") - public void testNullableFunctionType() throws Exception { - runTest("testData/inspectionsLocal/redundantSuspend/nullableFunctionType.kt"); - } - - @TestMetadata("override.kt") - public void testOverride() throws Exception { - runTest("testData/inspectionsLocal/redundantSuspend/override.kt"); - } - - @TestMetadata("parenthesized.kt") - public void testParenthesized() throws Exception { - runTest("testData/inspectionsLocal/redundantSuspend/parenthesized.kt"); - } - - @TestMetadata("recursiveCall.kt") - public void testRecursiveCall() throws Exception { - runTest("testData/inspectionsLocal/redundantSuspend/recursiveCall.kt"); - } - - @TestMetadata("selfCallWithDifferentReceiver.kt") - public void testSelfCallWithDifferentReceiver() throws Exception { - runTest("testData/inspectionsLocal/redundantSuspend/selfCallWithDifferentReceiver.kt"); - } - } - @RunWith(JUnit3RunnerWithInners.class) @TestMetadata("testData/inspectionsLocal/redundantUnitExpression") public static class RedundantUnitExpression extends AbstractLocalInspectionTest { diff --git a/plugins/kotlin/idea/tests/testData/inspections/redundantSuspendModifier/inspectionData/inspections.test b/plugins/kotlin/idea/tests/testData/inspections/redundantSuspendModifier/inspectionData/inspections.test deleted file mode 100644 index f87aff072708..000000000000 --- a/plugins/kotlin/idea/tests/testData/inspections/redundantSuspendModifier/inspectionData/inspections.test +++ /dev/null @@ -1 +0,0 @@ -// INSPECTION_CLASS: org.jetbrains.kotlin.idea.inspections.RedundantSuspendModifierInspection diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/redundantSuspend/.inspection b/plugins/kotlin/idea/tests/testData/inspectionsLocal/redundantSuspend/.inspection deleted file mode 100644 index 434360ce1f69..000000000000 --- a/plugins/kotlin/idea/tests/testData/inspectionsLocal/redundantSuspend/.inspection +++ /dev/null @@ -1 +0,0 @@ -org.jetbrains.kotlin.idea.inspections.RedundantSuspendModifierInspection \ No newline at end of file diff --git a/plugins/kotlin/k2-fe10-bindings/resources/META-INF/fe10Binding.xml b/plugins/kotlin/k2-fe10-bindings/resources/META-INF/fe10Binding.xml index 54a25d4dbb33..b92e35666267 100644 --- a/plugins/kotlin/k2-fe10-bindings/resources/META-INF/fe10Binding.xml +++ b/plugins/kotlin/k2-fe10-bindings/resources/META-INF/fe10Binding.xml @@ -215,14 +215,6 @@ language="kotlin" key="inspection.redundant.object.type.check.display.name" bundle="messages.KotlinBundle"/> - - - -