diff --git a/idea/idea-frontend-independent/resources-en/messages/KotlinBundle.properties b/idea/idea-frontend-independent/resources-en/messages/KotlinBundle.properties index c2f3f9059c5..28cf8ab8804 100644 --- a/idea/idea-frontend-independent/resources-en/messages/KotlinBundle.properties +++ b/idea/idea-frontend-independent/resources-en/messages/KotlinBundle.properties @@ -1636,6 +1636,7 @@ add.braces=Add braces add.indices.to.for.loop=Add indices to 'for' loop add.jvmoverloads.annotation=Add '@JvmOverloads' annotation add.jvmstatic.annotation=Add '@JvmStatic' annotation +add.jvminline.annotation=Add '@JvmInline' annotation add.labeled.return.to.last.expression.in.a.lambda=Add labeled return to last expression in a lambda add.missing.component=Add missing component add.names.to.call.arguments=Add names to call arguments diff --git a/idea/resources/META-INF/inspections.xml b/idea/resources/META-INF/inspections.xml index 4717ddc6426..811c6a086cc 100644 --- a/idea/resources/META-INF/inspections.xml +++ b/idea/resources/META-INF/inspections.xml @@ -360,6 +360,11 @@ Kotlin + + org.jetbrains.kotlin.idea.intentions.AddJvmInlineIntention + Kotlin + + org.jetbrains.kotlin.idea.intentions.RemoveArgumentNameIntention Kotlin diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/AddJvmInlineIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/AddJvmInlineIntention.kt new file mode 100644 index 00000000000..8a755df135a --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/AddJvmInlineIntention.kt @@ -0,0 +1,52 @@ +/* + * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.idea.intentions + +import com.intellij.codeInsight.intention.HighPriorityAction +import com.intellij.codeInsight.intention.IntentionAction +import com.intellij.openapi.editor.Editor +import com.intellij.openapi.project.Project +import com.intellij.openapi.util.TextRange +import org.jetbrains.kotlin.diagnostics.Diagnostic +import org.jetbrains.kotlin.idea.KotlinBundle +import org.jetbrains.kotlin.idea.quickfix.KotlinQuickFixAction +import org.jetbrains.kotlin.idea.quickfix.KotlinSingleIntentionActionFactory +import org.jetbrains.kotlin.idea.util.addAnnotation +import org.jetbrains.kotlin.idea.util.application.runWriteAction +import org.jetbrains.kotlin.lexer.KtTokens +import org.jetbrains.kotlin.psi.KtClass +import org.jetbrains.kotlin.psi.KtFile +import org.jetbrains.kotlin.psi.KtModifierListOwner +import org.jetbrains.kotlin.psi.KtNamedDeclaration +import org.jetbrains.kotlin.psi.psiUtil.getParentOfType +import org.jetbrains.kotlin.resolve.JVM_INLINE_ANNOTATION_FQ_NAME +import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm + +class AddJvmInlineIntention : SelfTargetingRangeIntention( + KtClass::class.java, + KotlinBundle.lazyMessage("add.jvminline.annotation") +), HighPriorityAction { + override fun applyTo(element: KtClass, editor: Editor?) { + runWriteAction { + element.addAnnotation(JVM_INLINE_ANNOTATION_FQ_NAME) + } + } + + override fun applicabilityRange(element: KtClass): TextRange? { + if (!element.isValue()) return null + + val modifier = element.modifierList?.getModifier(KtTokens.VALUE_KEYWORD) ?: return null + return modifier.textRange + } + + companion object : KotlinSingleIntentionActionFactory() { + override fun createAction(diagnostic: Diagnostic): IntentionAction? { + val valueModifier = ErrorsJvm.VALUE_CLASS_WITHOUT_JVM_INLINE_ANNOTATION.cast(diagnostic) + val modifierListOwner = valueModifier.psiElement.getParentOfType(strict = true) ?: return null + return if (valueModifier != null) AddJvmInlineIntention() else null + } + } +} \ No newline at end of file diff --git a/idea/testData/intentions/addJvmInline/.intention b/idea/testData/intentions/addJvmInline/.intention new file mode 100644 index 00000000000..9dd71775cc7 --- /dev/null +++ b/idea/testData/intentions/addJvmInline/.intention @@ -0,0 +1 @@ +org.jetbrains.kotlin.idea.intentions.AddJvmInlineIntention diff --git a/idea/testData/intentions/addJvmInline/valueClass.kt b/idea/testData/intentions/addJvmInline/valueClass.kt new file mode 100644 index 00000000000..89a71aa0ac5 --- /dev/null +++ b/idea/testData/intentions/addJvmInline/valueClass.kt @@ -0,0 +1,6 @@ +// WITH_RUNTIME + +// ERROR: Value classes without @JvmInline annotation are not supported yet +// SKIP_ERRORS_AFTER + +value class VC(val i: Int) \ No newline at end of file diff --git a/idea/testData/intentions/addJvmInline/valueClass.kt.after b/idea/testData/intentions/addJvmInline/valueClass.kt.after new file mode 100644 index 00000000000..124dc1b0c45 --- /dev/null +++ b/idea/testData/intentions/addJvmInline/valueClass.kt.after @@ -0,0 +1,7 @@ +// WITH_RUNTIME + +// ERROR: Value classes without @JvmInline annotation are not supported yet +// SKIP_ERRORS_AFTER + +@JvmInline +value class VC(val i: Int) \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java index 5364f343623..9d4dfa7700f 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java @@ -932,6 +932,24 @@ public class IntentionTestGenerated extends AbstractIntentionTest { } } + @TestMetadata("idea/testData/intentions/addJvmInline") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class AddJvmInline extends AbstractIntentionTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); + } + + public void testAllFilesPresentInAddJvmInline() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/testData/intentions/addJvmInline"), Pattern.compile("^([\\w\\-_]+)\\.(kt|kts)$"), null, true); + } + + @TestMetadata("valueClass.kt") + public void testValueClass() throws Exception { + runTest("idea/testData/intentions/addJvmInline/valueClass.kt"); + } + } + @TestMetadata("idea/testData/intentions/addJvmOverloads") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class)