diff --git a/idea/resources/inspectionDescriptions/RemoveAtFromAnnotationArgument.html b/idea/resources/inspectionDescriptions/RemoveAtFromAnnotationArgument.html new file mode 100644 index 00000000000..05643eb457c --- /dev/null +++ b/idea/resources/inspectionDescriptions/RemoveAtFromAnnotationArgument.html @@ -0,0 +1,5 @@ + + +This inspection detects unnecessary '@' at annotations which are annotation arguments themselves. + + \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/RemoveAtFromAnnotationArgumentIntention/after.kt.template b/idea/resources/intentionDescriptions/RemoveAtFromAnnotationArgumentIntention/after.kt.template new file mode 100644 index 00000000000..7fa1dd227a7 --- /dev/null +++ b/idea/resources/intentionDescriptions/RemoveAtFromAnnotationArgumentIntention/after.kt.template @@ -0,0 +1,6 @@ +annotation class X(val value: Y) +annotation class Y() + +@X(Y()) +fun foo() {} + \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/RemoveAtFromAnnotationArgumentIntention/before.kt.template b/idea/resources/intentionDescriptions/RemoveAtFromAnnotationArgumentIntention/before.kt.template new file mode 100644 index 00000000000..8428269659b --- /dev/null +++ b/idea/resources/intentionDescriptions/RemoveAtFromAnnotationArgumentIntention/before.kt.template @@ -0,0 +1,5 @@ +annotation class X(val value: Y) +annotation class Y() + +@X(@Y()) +fun foo() {} \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/RemoveAtFromAnnotationArgumentIntention/description.html b/idea/resources/intentionDescriptions/RemoveAtFromAnnotationArgumentIntention/description.html new file mode 100644 index 00000000000..52753fa911c --- /dev/null +++ b/idea/resources/intentionDescriptions/RemoveAtFromAnnotationArgumentIntention/description.html @@ -0,0 +1,5 @@ + + +This intention removes unnecessary '@' from annotations which are annotation arguments themselves. + + \ No newline at end of file diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml index d63993bca6e..4e33e1213ec 100644 --- a/idea/src/META-INF/plugin.xml +++ b/idea/src/META-INF/plugin.xml @@ -1255,6 +1255,11 @@ Kotlin + + org.jetbrains.kotlin.idea.intentions.RemoveAtFromAnnotationArgumentIntention + Kotlin + + + + diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveAtFromAnnotationArgumentIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveAtFromAnnotationArgumentIntention.kt new file mode 100644 index 00000000000..93c5ba458d7 --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveAtFromAnnotationArgumentIntention.kt @@ -0,0 +1,44 @@ +/* + * Copyright 2010-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.idea.intentions + +import com.intellij.openapi.editor.Editor +import org.jetbrains.kotlin.idea.inspections.IntentionBasedInspection +import org.jetbrains.kotlin.psi.KtAnnotatedExpression +import org.jetbrains.kotlin.psi.KtAnnotationEntry +import org.jetbrains.kotlin.psi.KtPsiFactory + +class RemoveAtFromAnnotationArgumentInspection : IntentionBasedInspection(RemoveAtFromAnnotationArgumentIntention()) + +class RemoveAtFromAnnotationArgumentIntention : SelfTargetingOffsetIndependentIntention( + KtAnnotatedExpression::class.java, + "Remove @ from annotation argument" +) { + override fun isApplicableTo(element: KtAnnotatedExpression): Boolean { + var parent = element.parent + while (parent != null) { + if (parent is KtAnnotationEntry) return true + parent = parent.parent + } + return false + } + + override fun applyTo(element: KtAnnotatedExpression, editor: Editor?) { + val noAt = KtPsiFactory(element.project).createExpression(element.text.replaceFirst("@", "")) + element.replace(noAt) + } +} \ No newline at end of file diff --git a/idea/testData/intentions/removeAtFromAnnotationArgument/.intention b/idea/testData/intentions/removeAtFromAnnotationArgument/.intention new file mode 100644 index 00000000000..295b958b15b --- /dev/null +++ b/idea/testData/intentions/removeAtFromAnnotationArgument/.intention @@ -0,0 +1 @@ +org.jetbrains.kotlin.idea.intentions.RemoveAtFromAnnotationArgumentIntention \ No newline at end of file diff --git a/idea/testData/intentions/removeAtFromAnnotationArgument/atmarkArgument.kt b/idea/testData/intentions/removeAtFromAnnotationArgument/atmarkArgument.kt new file mode 100644 index 00000000000..4ad94e185b8 --- /dev/null +++ b/idea/testData/intentions/removeAtFromAnnotationArgument/atmarkArgument.kt @@ -0,0 +1,8 @@ +// INTENTION_TEXT: Remove @ from annotation argument + +annotation class X(val value: Y) +annotation class Y() + +@X(@Y()) +fun foo() { +} \ No newline at end of file diff --git a/idea/testData/intentions/removeAtFromAnnotationArgument/atmarkArgument.kt.after b/idea/testData/intentions/removeAtFromAnnotationArgument/atmarkArgument.kt.after new file mode 100644 index 00000000000..d3dd56223f9 --- /dev/null +++ b/idea/testData/intentions/removeAtFromAnnotationArgument/atmarkArgument.kt.after @@ -0,0 +1,8 @@ +// INTENTION_TEXT: Remove @ from annotation argument + +annotation class X(val value: Y) +annotation class Y() + +@X(Y()) +fun foo() { +} \ No newline at end of file diff --git a/idea/testData/intentions/removeAtFromAnnotationArgument/atmarkArrayArguments.kt b/idea/testData/intentions/removeAtFromAnnotationArgument/atmarkArrayArguments.kt new file mode 100644 index 00000000000..fe5ea37d602 --- /dev/null +++ b/idea/testData/intentions/removeAtFromAnnotationArgument/atmarkArrayArguments.kt @@ -0,0 +1,9 @@ +// WITH_RUNTIME +// INTENTION_TEXT: Remove @ from annotation argument + +annotation class X(val value: Array) +annotation class Y() + +@X(arrayOf(Y(), @Y())) +fun foo() { +} \ No newline at end of file diff --git a/idea/testData/intentions/removeAtFromAnnotationArgument/atmarkArrayArguments.kt.after b/idea/testData/intentions/removeAtFromAnnotationArgument/atmarkArrayArguments.kt.after new file mode 100644 index 00000000000..73e663ffcbf --- /dev/null +++ b/idea/testData/intentions/removeAtFromAnnotationArgument/atmarkArrayArguments.kt.after @@ -0,0 +1,9 @@ +// WITH_RUNTIME +// INTENTION_TEXT: Remove @ from annotation argument + +annotation class X(val value: Array) +annotation class Y() + +@X(arrayOf(Y(), Y())) +fun foo() { +} \ No newline at end of file diff --git a/idea/testData/intentions/removeAtFromAnnotationArgument/multipleAtmarkArguments.kt b/idea/testData/intentions/removeAtFromAnnotationArgument/multipleAtmarkArguments.kt new file mode 100644 index 00000000000..30d0547b295 --- /dev/null +++ b/idea/testData/intentions/removeAtFromAnnotationArgument/multipleAtmarkArguments.kt @@ -0,0 +1,8 @@ +// INTENTION_TEXT: Remove @ from annotation argument + +annotation class X(val value: Y, val y: Y) +annotation class Y() + +@X(@Y(), y = @Y()) +fun foo() { +} \ No newline at end of file diff --git a/idea/testData/intentions/removeAtFromAnnotationArgument/multipleAtmarkArguments.kt.after b/idea/testData/intentions/removeAtFromAnnotationArgument/multipleAtmarkArguments.kt.after new file mode 100644 index 00000000000..5667186b6de --- /dev/null +++ b/idea/testData/intentions/removeAtFromAnnotationArgument/multipleAtmarkArguments.kt.after @@ -0,0 +1,8 @@ +// INTENTION_TEXT: Remove @ from annotation argument + +annotation class X(val value: Y, val y: Y) +annotation class Y() + +@X(@Y(), y = Y()) +fun foo() { +} \ No newline at end of file diff --git a/idea/testData/intentions/removeAtFromAnnotationArgument/stringAtmark.kt b/idea/testData/intentions/removeAtFromAnnotationArgument/stringAtmark.kt new file mode 100644 index 00000000000..5d0e550b3b7 --- /dev/null +++ b/idea/testData/intentions/removeAtFromAnnotationArgument/stringAtmark.kt @@ -0,0 +1,7 @@ +// IS_APPLICABLE: false + +annotation class X(val s: String) + +@X("@@@") +fun foo() { +} \ 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 65c08891acf..4d68d2d2911 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java @@ -7653,6 +7653,39 @@ public class IntentionTestGenerated extends AbstractIntentionTest { } } + @TestMetadata("idea/testData/intentions/removeAtFromAnnotationArgument") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class RemoveAtFromAnnotationArgument extends AbstractIntentionTest { + public void testAllFilesPresentInRemoveAtFromAnnotationArgument() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/intentions/removeAtFromAnnotationArgument"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), true); + } + + @TestMetadata("atmarkArgument.kt") + public void testAtmarkArgument() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/removeAtFromAnnotationArgument/atmarkArgument.kt"); + doTest(fileName); + } + + @TestMetadata("atmarkArrayArguments.kt") + public void testAtmarkArrayArguments() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/removeAtFromAnnotationArgument/atmarkArrayArguments.kt"); + doTest(fileName); + } + + @TestMetadata("multipleAtmarkArguments.kt") + public void testMultipleAtmarkArguments() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/removeAtFromAnnotationArgument/multipleAtmarkArguments.kt"); + doTest(fileName); + } + + @TestMetadata("stringAtmark.kt") + public void testStringAtmark() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/removeAtFromAnnotationArgument/stringAtmark.kt"); + doTest(fileName); + } + } + @TestMetadata("idea/testData/intentions/removeBraces") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class)