Add quickfix for "Illegal usage of inline parameter" that adds noinline (#888)
Fixes #KT-12838
This commit is contained in:
committed by
Dmitry Jemerov
parent
68dd3dde59
commit
3b290ce3dd
@@ -21,18 +21,22 @@ import com.intellij.openapi.editor.Editor
|
|||||||
import com.intellij.openapi.project.Project
|
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.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||||
|
|
||||||
class AddCrossInlineFix(element: KtNameReferenceExpression) : KotlinQuickFixAction<KtNameReferenceExpression>(element) {
|
class AddInlineModifierFix(
|
||||||
override fun getText() = "Add 'crossinline' to parameter '${element.getReferencedName()}'"
|
element: KtNameReferenceExpression,
|
||||||
override fun getFamilyName() = "Add 'crossinline' to parameter"
|
private val modifier: KtModifierKeywordToken
|
||||||
|
) : KotlinQuickFixAction<KtNameReferenceExpression>(element) {
|
||||||
|
override fun getText() = "Add '${modifier.value}' to parameter '${element.getReferencedName()}'"
|
||||||
|
override fun getFamilyName() = "Add '${modifier.value}' to parameter"
|
||||||
|
|
||||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||||
val parameter = element.findParameterWithName(element.getReferencedName()) ?: return
|
val parameter = element.findParameterWithName(element.getReferencedName()) ?: return
|
||||||
if (!parameter.hasModifier(KtTokens.CROSSINLINE_KEYWORD)) {
|
if (!parameter.hasModifier(modifier)) {
|
||||||
parameter.addModifier(KtTokens.CROSSINLINE_KEYWORD)
|
parameter.addModifier(modifier)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,11 +45,19 @@ class AddCrossInlineFix(element: KtNameReferenceExpression) : KotlinQuickFixActi
|
|||||||
return function.valueParameters.firstOrNull { it.name == name } ?: function.findParameterWithName(name)
|
return function.valueParameters.firstOrNull { it.name == name } ?: function.findParameterWithName(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object Factory : KotlinIntentionActionsFactory() {
|
object CrossInlineFactory : KotlinIntentionActionsFactory() {
|
||||||
override fun doCreateActions(diagnostic: Diagnostic): List<IntentionAction> {
|
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 emptyList()
|
||||||
return listOf(AddCrossInlineFix(reference))
|
return listOf(AddInlineModifierFix(reference, KtTokens.CROSSINLINE_KEYWORD))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object NoInlineFactory : KotlinIntentionActionsFactory() {
|
||||||
|
override fun doCreateActions(diagnostic: Diagnostic): List<IntentionAction> {
|
||||||
|
val casted = Errors.USAGE_IS_NOT_INLINABLE.cast(diagnostic)
|
||||||
|
val reference = casted.a as? KtNameReferenceExpression ?: return emptyList()
|
||||||
|
return listOf(AddInlineModifierFix(reference, KtTokens.NOINLINE_KEYWORD))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -390,7 +390,8 @@ class QuickFixRegistrar : QuickFixContributor {
|
|||||||
|
|
||||||
DATA_CLASS_NOT_PROPERTY_PARAMETER.registerFactory(AddValVarToConstructorParameterAction.QuickFixFactory)
|
DATA_CLASS_NOT_PROPERTY_PARAMETER.registerFactory(AddValVarToConstructorParameterAction.QuickFixFactory)
|
||||||
|
|
||||||
NON_LOCAL_RETURN_NOT_ALLOWED.registerFactory(AddCrossInlineFix)
|
NON_LOCAL_RETURN_NOT_ALLOWED.registerFactory(AddInlineModifierFix.CrossInlineFactory)
|
||||||
|
USAGE_IS_NOT_INLINABLE.registerFactory(AddInlineModifierFix.NoInlineFactory)
|
||||||
|
|
||||||
UNRESOLVED_REFERENCE.registerFactory(MakeConstructorParameterPropertyFix)
|
UNRESOLVED_REFERENCE.registerFactory(MakeConstructorParameterPropertyFix)
|
||||||
|
|
||||||
|
|||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
// "Add 'noinline' to parameter 'block'" "true"
|
||||||
|
|
||||||
|
inline fun foo(block: () -> Unit) = block<caret>
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
// "Add 'noinline' to parameter 'block'" "true"
|
||||||
|
|
||||||
|
inline fun foo(noinline block: () -> Unit) = block<caret>
|
||||||
@@ -383,6 +383,21 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("idea/testData/quickfix/addNoinline")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class AddNoinline extends AbstractQuickFixTest {
|
||||||
|
public void testAllFilesPresentInAddNoinline() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/addNoinline"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("basic.kt")
|
||||||
|
public void testBasic() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/addNoinline/basic.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("idea/testData/quickfix/addRunBeforeLambda")
|
@TestMetadata("idea/testData/quickfix/addRunBeforeLambda")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
|||||||
Reference in New Issue
Block a user