Quick-fix to add noinline to parameter with suspend function type + AddInlineModifierFix refactoring #KT-16074 Fixed
This commit is contained in:
+27
-24
@@ -17,8 +17,6 @@
|
|||||||
package org.jetbrains.kotlin.idea.quickfix
|
package org.jetbrains.kotlin.idea.quickfix
|
||||||
|
|
||||||
import com.intellij.codeInsight.intention.IntentionAction
|
import com.intellij.codeInsight.intention.IntentionAction
|
||||||
import com.intellij.openapi.editor.Editor
|
|
||||||
import com.intellij.openapi.project.Project
|
|
||||||
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
||||||
import org.jetbrains.kotlin.diagnostics.Errors
|
import org.jetbrains.kotlin.diagnostics.Errors
|
||||||
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
||||||
@@ -27,38 +25,43 @@ import org.jetbrains.kotlin.psi.*
|
|||||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||||
|
|
||||||
class AddInlineModifierFix(
|
class AddInlineModifierFix(
|
||||||
element: KtNameReferenceExpression,
|
parameter: KtParameter,
|
||||||
private val modifier: KtModifierKeywordToken
|
modifier: KtModifierKeywordToken
|
||||||
) : KotlinQuickFixAction<KtNameReferenceExpression>(element) {
|
) : AddModifierFix(parameter, modifier) {
|
||||||
override fun getText() = element?.let { "Add '${modifier.value}' to parameter '${it.getReferencedName()}'" } ?: ""
|
|
||||||
|
override fun getText() = element?.let { "Add '${modifier.value}' to parameter '${it.name}'" } ?: ""
|
||||||
override fun getFamilyName() = "Add '${modifier.value}' to parameter"
|
override fun getFamilyName() = "Add '${modifier.value}' to parameter"
|
||||||
|
|
||||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
companion object {
|
||||||
val element = element ?: return
|
private fun KtElement.findParameterWithName(name: String): KtParameter? {
|
||||||
val parameter = element.findParameterWithName(element.getReferencedName()) ?: return
|
val function = getStrictParentOfType<KtFunction>() ?: return null
|
||||||
if (!parameter.hasModifier(modifier)) {
|
return function.valueParameters.firstOrNull { it.name == name } ?: function.findParameterWithName(name)
|
||||||
parameter.addModifier(modifier)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun KtElement.findParameterWithName(name: String): KtParameter? {
|
object CrossInlineFactory : KotlinSingleIntentionActionFactory() {
|
||||||
val function = getStrictParentOfType<KtFunction>() ?: return null
|
override fun createAction(diagnostic: Diagnostic): IntentionAction? {
|
||||||
return function.valueParameters.firstOrNull { it.name == name } ?: function.findParameterWithName(name)
|
|
||||||
}
|
|
||||||
|
|
||||||
object CrossInlineFactory : KotlinIntentionActionsFactory() {
|
|
||||||
override fun doCreateActions(diagnostic: Diagnostic): List<IntentionAction> {
|
|
||||||
val casted = Errors.NON_LOCAL_RETURN_NOT_ALLOWED.cast(diagnostic)
|
val casted = Errors.NON_LOCAL_RETURN_NOT_ALLOWED.cast(diagnostic)
|
||||||
val reference = casted.a as? KtNameReferenceExpression ?: return emptyList()
|
val reference = casted.a as? KtNameReferenceExpression ?: return null
|
||||||
return listOf(AddInlineModifierFix(reference, KtTokens.CROSSINLINE_KEYWORD))
|
val parameter = reference.findParameterWithName(reference.getReferencedName()) ?: return null
|
||||||
|
return AddInlineModifierFix(parameter, KtTokens.CROSSINLINE_KEYWORD)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
object NoInlineFactory : KotlinIntentionActionsFactory() {
|
object NoInlineFactory : KotlinSingleIntentionActionFactory() {
|
||||||
override fun doCreateActions(diagnostic: Diagnostic): List<IntentionAction> {
|
override fun createAction(diagnostic: Diagnostic): IntentionAction? {
|
||||||
val casted = Errors.USAGE_IS_NOT_INLINABLE.cast(diagnostic)
|
val casted = Errors.USAGE_IS_NOT_INLINABLE.cast(diagnostic)
|
||||||
val reference = casted.a as? KtNameReferenceExpression ?: return emptyList()
|
val reference = casted.a as? KtNameReferenceExpression ?: return null
|
||||||
return listOf(AddInlineModifierFix(reference, KtTokens.NOINLINE_KEYWORD))
|
val parameter = reference.findParameterWithName(reference.getReferencedName()) ?: return null
|
||||||
|
return AddInlineModifierFix(parameter, KtTokens.NOINLINE_KEYWORD)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object SuspendFactory : KotlinSingleIntentionActionFactory() {
|
||||||
|
override fun createAction(diagnostic: Diagnostic): IntentionAction? {
|
||||||
|
val parameter = diagnostic.psiElement as? KtParameter ?: return null
|
||||||
|
return AddInlineModifierFix(parameter, KtTokens.NOINLINE_KEYWORD)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -37,7 +37,7 @@ import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
|||||||
|
|
||||||
open class AddModifierFix(
|
open class AddModifierFix(
|
||||||
element: KtModifierListOwner,
|
element: KtModifierListOwner,
|
||||||
private val modifier: KtModifierKeywordToken
|
protected val modifier: KtModifierKeywordToken
|
||||||
) : KotlinQuickFixAction<KtModifierListOwner>(element) {
|
) : KotlinQuickFixAction<KtModifierListOwner>(element) {
|
||||||
|
|
||||||
override fun getText(): String {
|
override fun getText(): String {
|
||||||
|
|||||||
@@ -470,6 +470,8 @@ class QuickFixRegistrar : QuickFixContributor {
|
|||||||
ErrorsJs.WRONG_EXTERNAL_DECLARATION.registerFactory(MigrateExternalExtensionFix)
|
ErrorsJs.WRONG_EXTERNAL_DECLARATION.registerFactory(MigrateExternalExtensionFix)
|
||||||
|
|
||||||
ILLEGAL_SUSPEND_FUNCTION_CALL.registerFactory(AddSuspendModifierFix)
|
ILLEGAL_SUSPEND_FUNCTION_CALL.registerFactory(AddSuspendModifierFix)
|
||||||
|
INLINE_SUSPEND_FUNCTION_TYPE_UNSUPPORTED.registerFactory(AddInlineModifierFix.SuspendFactory)
|
||||||
|
|
||||||
UNRESOLVED_REFERENCE.registerFactory(AddSuspendModifierFix.UnresolvedReferenceFactory)
|
UNRESOLVED_REFERENCE.registerFactory(AddSuspendModifierFix.UnresolvedReferenceFactory)
|
||||||
UNRESOLVED_REFERENCE_WRONG_RECEIVER.registerFactory(AddSuspendModifierFix.UnresolvedReferenceFactory)
|
UNRESOLVED_REFERENCE_WRONG_RECEIVER.registerFactory(AddSuspendModifierFix.UnresolvedReferenceFactory)
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
// "Add 'noinline' to parameter 'x'" "true"
|
||||||
|
|
||||||
|
inline fun foo(<caret>x: suspend () -> Unit) {}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
// "Add 'noinline' to parameter 'x'" "true"
|
||||||
|
|
||||||
|
inline fun foo(noinline x: suspend () -> Unit) {}
|
||||||
@@ -445,6 +445,12 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
|
|||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/addNoinline/basic.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/addNoinline/basic.kt");
|
||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("suspend.kt")
|
||||||
|
public void testSuspend() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/addNoinline/suspend.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("idea/testData/quickfix/addReifiedToTypeParameterOfFunctionFix")
|
@TestMetadata("idea/testData/quickfix/addReifiedToTypeParameterOfFunctionFix")
|
||||||
|
|||||||
Reference in New Issue
Block a user