mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[Kotlin] Ported redundant suspend modifier inspection to analysis API
^KTIJ-29049 fixed GitOrigin-RevId: 29be464acca9da87da63bce08d2701ea6187d8d4
This commit is contained in:
committed by
intellij-monorepo-bot
parent
6577acb998
commit
5e0cc70bbb
+8
@@ -97,6 +97,14 @@
|
||||
language="kotlin"
|
||||
key="inspection.redundant.setter.display.name" bundle="messages.KotlinBundle"/>
|
||||
|
||||
<localInspection implementationClass="org.jetbrains.kotlin.idea.codeInsight.inspections.shared.RedundantSuspendModifierInspection"
|
||||
groupPath="Kotlin"
|
||||
groupBundle="messages.KotlinBundle" groupKey="group.names.redundant.constructs"
|
||||
enabledByDefault="true"
|
||||
level="WARNING"
|
||||
language="kotlin" editorAttributes="NOT_USED_ELEMENT_ATTRIBUTES"
|
||||
key="inspection.redundant.suspend.modifier.display.name" bundle="messages.KotlinBundle"/>
|
||||
|
||||
<localInspection
|
||||
implementationClass="org.jetbrains.kotlin.idea.codeInsight.inspections.shared.SimplifyNegatedBinaryExpressionInspection"
|
||||
groupPath="Kotlin"
|
||||
|
||||
+127
@@ -0,0 +1,127 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package org.jetbrains.kotlin.idea.codeInsight.inspections.shared
|
||||
|
||||
import com.intellij.codeInspection.IntentionWrapper
|
||||
import com.intellij.codeInspection.LocalInspectionToolSession
|
||||
import com.intellij.codeInspection.ProblemsHolder
|
||||
import com.intellij.psi.PsiElementVisitor
|
||||
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
|
||||
import org.jetbrains.kotlin.analysis.api.analyze
|
||||
import org.jetbrains.kotlin.analysis.api.calls.*
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtCallableSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtFunctionSymbol
|
||||
import org.jetbrains.kotlin.builtins.StandardNames
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.idea.base.projectStructure.languageVersionSettings
|
||||
import org.jetbrains.kotlin.idea.base.resources.KotlinBundle
|
||||
import org.jetbrains.kotlin.idea.codeinsight.api.classic.inspections.AbstractKotlinInspection
|
||||
import org.jetbrains.kotlin.idea.codeinsight.utils.getFqNameIfPackageOrNonLocal
|
||||
import org.jetbrains.kotlin.idea.quickfix.RemoveModifierFixBase
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.anyDescendantOfType
|
||||
|
||||
internal 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
|
||||
|
||||
analyze(function) {
|
||||
val functionSymbol = function.getFunctionLikeSymbol() as? KtFunctionSymbol ?: return
|
||||
if (functionSymbol.modality == Modality.OPEN) return
|
||||
|
||||
if (function.hasSuspendOrUnresolvedCall(functionSymbol)) return
|
||||
|
||||
holder.registerProblem(
|
||||
suspendModifier, KotlinBundle.message("redundant.suspend.modifier"), IntentionWrapper(
|
||||
RemoveModifierFixBase(function, KtTokens.SUSPEND_KEYWORD, isRedundant = true).asIntention()
|
||||
)
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private val coroutineContextFqName = StandardNames.COROUTINES_PACKAGE_FQ_NAME.child(Name.identifier("coroutineContext"))
|
||||
|
||||
context(KtAnalysisSession)
|
||||
private fun KtCallableSymbol.isSuspendSymbol(): Boolean {
|
||||
|
||||
// Currently, Kotlin does not support suspending properties except for accessing the coroutineContext
|
||||
if (getFqNameIfPackageOrNonLocal() == coroutineContextFqName) {
|
||||
return true
|
||||
}
|
||||
|
||||
return this is KtFunctionSymbol && isSuspend
|
||||
}
|
||||
|
||||
context(KtAnalysisSession)
|
||||
private fun KtExpression.resolveMemberFunction(
|
||||
name: String,
|
||||
psiFactory: KtPsiFactory,
|
||||
context: KtExpression = this
|
||||
): KtFunctionCall<*>? {
|
||||
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<KtCallableMemberCall<*, *>>() ?: 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<KtExpression> { 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
+17
@@ -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 {
|
||||
|
||||
+128
@@ -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 {
|
||||
|
||||
+17
@@ -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 {
|
||||
|
||||
+128
@@ -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 {
|
||||
|
||||
+2
@@ -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
|
||||
+1
@@ -0,0 +1 @@
|
||||
org.jetbrains.kotlin.idea.codeInsight.inspections.shared.RedundantSuspendModifierInspection
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
// PROBLEM: none
|
||||
|
||||
interface Suspended {
|
||||
<caret>suspend fun bar() {
|
||||
|
||||
}
|
||||
}
|
||||
+6
@@ -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 {
|
||||
<caret>suspend fun bar()
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
class Iterable {
|
||||
operator fun iterator() = this
|
||||
operator fun hasNext(): Boolean = false
|
||||
operator fun next(): Int = 0
|
||||
}
|
||||
|
||||
<caret>suspend fun foo() {
|
||||
val iterable = Iterable()
|
||||
for (x in iterable) {
|
||||
}
|
||||
}
|
||||
+11
@@ -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) {
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
class SIterable {
|
||||
}
|
||||
|
||||
operator fun SIterable.iterator() = this
|
||||
operator fun SIterable.hasNext(): Boolean = false
|
||||
operator fun SIterable.next(): Int = 0
|
||||
|
||||
<caret>suspend fun foo() {
|
||||
val iterable = SIterable()
|
||||
for (x in iterable) {
|
||||
}
|
||||
}
|
||||
+12
@@ -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) {
|
||||
}
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
class OtherIterator {
|
||||
operator fun hasNext(): Boolean = false
|
||||
operator fun next(): Int = 0
|
||||
}
|
||||
|
||||
class SIterable {
|
||||
operator fun iterator() = OtherIterator()
|
||||
}
|
||||
|
||||
<caret>suspend fun foo() {
|
||||
val iterable = SIterable()
|
||||
for (x in iterable) {
|
||||
}
|
||||
}
|
||||
+14
@@ -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) {
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
class SIterable {
|
||||
}
|
||||
|
||||
<caret>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) {
|
||||
}
|
||||
}
|
||||
+12
@@ -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) {
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
// PROBLEM: none
|
||||
|
||||
class A(val x: Int) {
|
||||
suspend operator fun plus(a: A): A = A(1)
|
||||
}
|
||||
|
||||
<caret>suspend fun foo(a1: A, a2: A): A {
|
||||
return a1 + a2
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
// PROBLEM: none
|
||||
|
||||
class A(val x: Int) {
|
||||
suspend operator fun plus(a: A): A = A(1)
|
||||
}
|
||||
|
||||
<caret>suspend fun foo(a1: A, a2: A) {
|
||||
var a = a1
|
||||
a += a2
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
class A(val x: Int) {
|
||||
<caret>suspend operator fun plus(a: A): A {
|
||||
return a + a
|
||||
}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
class A(val x: Int) {
|
||||
operator fun plus(a: A): A {
|
||||
return a + a
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
class A(val x: Int) {
|
||||
<caret>suspend operator fun plus(a: A): A {
|
||||
var a = a
|
||||
a += a
|
||||
return a
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
class A(val x: Int) {
|
||||
operator fun plus(a: A): A {
|
||||
var a = a
|
||||
a += a
|
||||
return a
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
// PROBLEM: none
|
||||
|
||||
class SIterable {
|
||||
operator fun iterator() = this
|
||||
suspend operator fun hasNext(): Boolean = false
|
||||
suspend operator fun next(): Int = 0
|
||||
}
|
||||
|
||||
<caret>suspend fun foo() {
|
||||
val iterable = SIterable()
|
||||
for (x in iterable) {
|
||||
}
|
||||
}
|
||||
+15
@@ -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
|
||||
|
||||
<caret>suspend fun foo() {
|
||||
val iterable = SIterable()
|
||||
for (x in iterable) {
|
||||
}
|
||||
}
|
||||
+17
@@ -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()
|
||||
}
|
||||
|
||||
<caret>suspend fun foo() {
|
||||
val iterable = SIterable()
|
||||
for (x in iterable) {
|
||||
}
|
||||
}
|
||||
+15
@@ -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 {
|
||||
}
|
||||
|
||||
<caret>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) {
|
||||
}
|
||||
}
|
||||
-83
@@ -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<KtExpression> { 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
|
||||
}
|
||||
}
|
||||
}
|
||||
-5
@@ -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");
|
||||
|
||||
-58
@@ -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 {
|
||||
|
||||
-1
@@ -1 +0,0 @@
|
||||
// INSPECTION_CLASS: org.jetbrains.kotlin.idea.inspections.RedundantSuspendModifierInspection
|
||||
@@ -1 +0,0 @@
|
||||
org.jetbrains.kotlin.idea.inspections.RedundantSuspendModifierInspection
|
||||
@@ -215,14 +215,6 @@
|
||||
language="kotlin"
|
||||
key="inspection.redundant.object.type.check.display.name" bundle="messages.KotlinBundle"/>
|
||||
|
||||
<localInspection implementationClass="org.jetbrains.kotlin.idea.inspections.RedundantSuspendModifierInspection"
|
||||
groupPath="Kotlin"
|
||||
groupBundle="messages.KotlinBundle" groupKey="group.names.redundant.constructs"
|
||||
enabledByDefault="true"
|
||||
level="WARNING"
|
||||
language="kotlin" editorAttributes="NOT_USED_ELEMENT_ATTRIBUTES"
|
||||
key="inspection.redundant.suspend.modifier.display.name" bundle="messages.KotlinBundle"/>
|
||||
|
||||
<localInspection implementationClass="org.jetbrains.kotlin.idea.inspections.RedundantExplicitTypeInspection"
|
||||
groupPath="Kotlin"
|
||||
groupBundle="messages.KotlinBundle" groupKey="group.names.redundant.constructs"
|
||||
|
||||
-58
@@ -1561,64 +1561,6 @@ public abstract class Fe10BindingLocalInspectionTestGenerated extends AbstractFe
|
||||
}
|
||||
}
|
||||
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@TestMetadata("../idea/tests/testData/inspectionsLocal/redundantSuspend")
|
||||
public static class RedundantSuspend extends AbstractFe10BindingLocalInspectionTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
@TestMetadata("actual.kt")
|
||||
public void testActual() throws Exception {
|
||||
runTest("../idea/tests/testData/inspectionsLocal/redundantSuspend/actual.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("coroutineContext.kt")
|
||||
public void testCoroutineContext() throws Exception {
|
||||
runTest("../idea/tests/testData/inspectionsLocal/redundantSuspend/coroutineContext.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("invokeOperator.kt")
|
||||
public void testInvokeOperator() throws Exception {
|
||||
runTest("../idea/tests/testData/inspectionsLocal/redundantSuspend/invokeOperator.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("invokingByQualified.kt")
|
||||
public void testInvokingByQualified() throws Exception {
|
||||
runTest("../idea/tests/testData/inspectionsLocal/redundantSuspend/invokingByQualified.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("lambdaCall.kt")
|
||||
public void testLambdaCall() throws Exception {
|
||||
runTest("../idea/tests/testData/inspectionsLocal/redundantSuspend/lambdaCall.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("nullableFunctionType.kt")
|
||||
public void testNullableFunctionType() throws Exception {
|
||||
runTest("../idea/tests/testData/inspectionsLocal/redundantSuspend/nullableFunctionType.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("override.kt")
|
||||
public void testOverride() throws Exception {
|
||||
runTest("../idea/tests/testData/inspectionsLocal/redundantSuspend/override.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("parenthesized.kt")
|
||||
public void testParenthesized() throws Exception {
|
||||
runTest("../idea/tests/testData/inspectionsLocal/redundantSuspend/parenthesized.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("recursiveCall.kt")
|
||||
public void testRecursiveCall() throws Exception {
|
||||
runTest("../idea/tests/testData/inspectionsLocal/redundantSuspend/recursiveCall.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("selfCallWithDifferentReceiver.kt")
|
||||
public void testSelfCallWithDifferentReceiver() throws Exception {
|
||||
runTest("../idea/tests/testData/inspectionsLocal/redundantSuspend/selfCallWithDifferentReceiver.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@TestMetadata("../idea/tests/testData/inspectionsLocal/redundantExplicitType")
|
||||
public static class RedundantExplicitType extends AbstractFe10BindingLocalInspectionTest {
|
||||
|
||||
@@ -1916,14 +1916,6 @@
|
||||
language="kotlin"
|
||||
key="inspection.replace.put.with.assignment.display.name" bundle="messages.KotlinBundle"/>
|
||||
|
||||
<localInspection implementationClass="org.jetbrains.kotlin.idea.inspections.RedundantSuspendModifierInspection"
|
||||
groupPath="Kotlin"
|
||||
groupBundle="messages.KotlinBundle" groupKey="group.names.redundant.constructs"
|
||||
enabledByDefault="true"
|
||||
level="WARNING"
|
||||
language="kotlin" editorAttributes="NOT_USED_ELEMENT_ATTRIBUTES"
|
||||
key="inspection.redundant.suspend.modifier.display.name" bundle="messages.KotlinBundle"/>
|
||||
|
||||
<localInspection implementationClass="org.jetbrains.kotlin.idea.inspections.MayBeConstantInspection"
|
||||
groupPath="Kotlin"
|
||||
groupBundle="messages.KotlinBundle" groupKey="group.names.style.issues"
|
||||
|
||||
-1
@@ -38,7 +38,6 @@ internal fun MutableTWorkspace.generateK2Fe10BindingsTests() {
|
||||
model("testData/inspectionsLocal/mapGetWithNotNullAssertionOperator", pattern = pattern)
|
||||
model("testData/inspectionsLocal/memberVisibilityCanBePrivate", pattern = pattern)
|
||||
model("testData/inspectionsLocal/redundantObjectTypeCheck", pattern = pattern)
|
||||
model("testData/inspectionsLocal/redundantSuspend", pattern = pattern)
|
||||
model("testData/inspectionsLocal/redundantExplicitType", pattern = pattern)
|
||||
model("testData/inspectionsLocal/replaceArrayEqualityOpWithArraysEquals", pattern = pattern)
|
||||
model("testData/inspectionsLocal/replaceAssociateFunction", pattern = pattern)
|
||||
|
||||
Reference in New Issue
Block a user