diff --git a/idea/src/org/jetbrains/kotlin/idea/codeInliner/ReplacementPerformer.kt b/idea/src/org/jetbrains/kotlin/idea/codeInliner/ReplacementPerformer.kt index 14e67cfbdc0..096c0a61b86 100644 --- a/idea/src/org/jetbrains/kotlin/idea/codeInliner/ReplacementPerformer.kt +++ b/idea/src/org/jetbrains/kotlin/idea/codeInliner/ReplacementPerformer.kt @@ -19,6 +19,7 @@ package org.jetbrains.kotlin.idea.codeInliner import com.intellij.openapi.util.Key import com.intellij.psi.PsiTreeChangeAdapter import com.intellij.psi.PsiTreeChangeEvent +import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.core.canDropBraces import org.jetbrains.kotlin.idea.core.dropBraces @@ -51,6 +52,10 @@ internal class AnnotationEntryReplacementPerformer( assert(codeToInline.mainExpression != null) assert(codeToInline.statementsBefore.isEmpty()) + val useSiteTarget = elementToBeReplaced.useSiteTarget?.getAnnotationUseSiteTarget() + val useSiteTargetText = useSiteTarget?.renderName?.let { "$it:" } ?: "" + val isFileUseSiteTarget = useSiteTarget == AnnotationUseSiteTarget.FILE + val dummyAnnotationEntry = createByPattern("@Dummy($0)", codeToInline.mainExpression!!) { psiFactory.createAnnotationEntry(it) } val replaced = elementToBeReplaced.replace(dummyAnnotationEntry) @@ -63,7 +68,11 @@ internal class AnnotationEntryReplacementPerformer( assert(range.first is KtAnnotationEntry) val annotationEntry = range.first as KtAnnotationEntry val text = annotationEntry.valueArguments.single().getArgumentExpression()!!.text - return annotationEntry.replaced(psiFactory.createAnnotationEntry("@$text")) + val newAnnotationEntry = if (isFileUseSiteTarget) + psiFactory.createFileAnnotation(text) + else + psiFactory.createAnnotationEntry("@$useSiteTargetText$text") + return annotationEntry.replaced(newAnnotationEntry) } } diff --git a/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/annotationWithFileUseSiteTarget1.kt b/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/annotationWithFileUseSiteTarget1.kt new file mode 100644 index 00000000000..b9f9e39b8a1 --- /dev/null +++ b/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/annotationWithFileUseSiteTarget1.kt @@ -0,0 +1,3 @@ +// "Replace with 'OptIn(*markerClass)'" "true" +// WITH_RUNTIME +@file:UseExperimental \ No newline at end of file diff --git a/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/annotationWithFileUseSiteTarget1.kt.after b/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/annotationWithFileUseSiteTarget1.kt.after new file mode 100644 index 00000000000..7a8b0ea9a99 --- /dev/null +++ b/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/annotationWithFileUseSiteTarget1.kt.after @@ -0,0 +1,3 @@ +// "Replace with 'OptIn(*markerClass)'" "true" +// WITH_RUNTIME +@file:OptIn() \ No newline at end of file diff --git a/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/annotationWithFileUseSiteTarget2.kt b/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/annotationWithFileUseSiteTarget2.kt new file mode 100644 index 00000000000..05adf9fae9d --- /dev/null +++ b/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/annotationWithFileUseSiteTarget2.kt @@ -0,0 +1,3 @@ +// "Replace with 'OptIn(*markerClass)'" "true" +// WITH_RUNTIME +@file:UseExperimental() \ No newline at end of file diff --git a/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/annotationWithFileUseSiteTarget2.kt.after b/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/annotationWithFileUseSiteTarget2.kt.after new file mode 100644 index 00000000000..df0bcc391dd --- /dev/null +++ b/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/annotationWithFileUseSiteTarget2.kt.after @@ -0,0 +1,3 @@ +// "Replace with 'OptIn(*markerClass)'" "true" +// WITH_RUNTIME +@file:OptIn() \ No newline at end of file diff --git a/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/annotationWithFileUseSiteTarget3.kt b/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/annotationWithFileUseSiteTarget3.kt new file mode 100644 index 00000000000..34376807732 --- /dev/null +++ b/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/annotationWithFileUseSiteTarget3.kt @@ -0,0 +1,6 @@ +// "Replace with 'OptIn(*markerClass)'" "true" +// WITH_RUNTIME +@file:UseExperimental(Foo::class, Bar::class) + +annotation class Foo +annotation class Bar \ No newline at end of file diff --git a/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/annotationWithFileUseSiteTarget3.kt.after b/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/annotationWithFileUseSiteTarget3.kt.after new file mode 100644 index 00000000000..fe59c4ad48a --- /dev/null +++ b/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/annotationWithFileUseSiteTarget3.kt.after @@ -0,0 +1,6 @@ +// "Replace with 'OptIn(*markerClass)'" "true" +// WITH_RUNTIME +@file:OptIn(Foo::class, Bar::class) + +annotation class Foo +annotation class Bar \ No newline at end of file diff --git a/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/annotationWithGetUseSiteTarget1.kt b/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/annotationWithGetUseSiteTarget1.kt new file mode 100644 index 00000000000..cc6719b4ac9 --- /dev/null +++ b/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/annotationWithGetUseSiteTarget1.kt @@ -0,0 +1,12 @@ +// "Replace with 'Bar'" "true" +class Test { + @get:Foo + val s: String = "" +} + +@Deprecated("Replace with Bar", ReplaceWith("Bar")) +@Target(AnnotationTarget.PROPERTY_GETTER) +annotation class Foo + +@Target(AnnotationTarget.PROPERTY_GETTER) +annotation class Bar \ No newline at end of file diff --git a/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/annotationWithGetUseSiteTarget1.kt.after b/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/annotationWithGetUseSiteTarget1.kt.after new file mode 100644 index 00000000000..2127104b9d2 --- /dev/null +++ b/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/annotationWithGetUseSiteTarget1.kt.after @@ -0,0 +1,12 @@ +// "Replace with 'Bar'" "true" +class Test { + @get:Bar + val s: String = "" +} + +@Deprecated("Replace with Bar", ReplaceWith("Bar")) +@Target(AnnotationTarget.PROPERTY_GETTER) +annotation class Foo + +@Target(AnnotationTarget.PROPERTY_GETTER) +annotation class Bar \ No newline at end of file diff --git a/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/annotationWithGetUseSiteTarget2.kt b/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/annotationWithGetUseSiteTarget2.kt new file mode 100644 index 00000000000..1850efb9670 --- /dev/null +++ b/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/annotationWithGetUseSiteTarget2.kt @@ -0,0 +1,12 @@ +// "Replace with 'Bar()'" "true" +class Test { + @get:Foo + val s: String = "" +} + +@Deprecated("Replace with Bar", ReplaceWith("Bar()")) +@Target(AnnotationTarget.PROPERTY_GETTER) +annotation class Foo + +@Target(AnnotationTarget.PROPERTY_GETTER) +annotation class Bar \ No newline at end of file diff --git a/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/annotationWithGetUseSiteTarget2.kt.after b/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/annotationWithGetUseSiteTarget2.kt.after new file mode 100644 index 00000000000..771e18554a6 --- /dev/null +++ b/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/annotationWithGetUseSiteTarget2.kt.after @@ -0,0 +1,12 @@ +// "Replace with 'Bar()'" "true" +class Test { + @get:Bar() + val s: String = "" +} + +@Deprecated("Replace with Bar", ReplaceWith("Bar()")) +@Target(AnnotationTarget.PROPERTY_GETTER) +annotation class Foo + +@Target(AnnotationTarget.PROPERTY_GETTER) +annotation class Bar \ No newline at end of file diff --git a/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/annotationWithGetUseSiteTarget3.kt b/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/annotationWithGetUseSiteTarget3.kt new file mode 100644 index 00000000000..c9ccc3f1c55 --- /dev/null +++ b/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/annotationWithGetUseSiteTarget3.kt @@ -0,0 +1,12 @@ +// "Replace with 'Bar(i)'" "true" +class Test { + @get:Foo(1) + val s: String = "" +} + +@Deprecated("Replace with Bar", ReplaceWith("Bar(i)")) +@Target(AnnotationTarget.PROPERTY_GETTER) +annotation class Foo(val i: Int) + +@Target(AnnotationTarget.PROPERTY_GETTER) +annotation class Bar(val i: Int) \ No newline at end of file diff --git a/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/annotationWithGetUseSiteTarget3.kt.after b/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/annotationWithGetUseSiteTarget3.kt.after new file mode 100644 index 00000000000..5d560b73fd3 --- /dev/null +++ b/idea/testData/quickfix/deprecatedSymbolUsage/classUsages/annotationWithGetUseSiteTarget3.kt.after @@ -0,0 +1,12 @@ +// "Replace with 'Bar(i)'" "true" +class Test { + @get:Bar(1) + val s: String = "" +} + +@Deprecated("Replace with Bar", ReplaceWith("Bar(i)")) +@Target(AnnotationTarget.PROPERTY_GETTER) +annotation class Foo(val i: Int) + +@Target(AnnotationTarget.PROPERTY_GETTER) +annotation class Bar(val i: Int) \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java index 2fd67775c45..f0a6af63fc9 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java @@ -6417,6 +6417,36 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { runTest("idea/testData/quickfix/deprecatedSymbolUsage/classUsages/annotationKeepNamedArgs.kt"); } + @TestMetadata("annotationWithFileUseSiteTarget1.kt") + public void testAnnotationWithFileUseSiteTarget1() throws Exception { + runTest("idea/testData/quickfix/deprecatedSymbolUsage/classUsages/annotationWithFileUseSiteTarget1.kt"); + } + + @TestMetadata("annotationWithFileUseSiteTarget2.kt") + public void testAnnotationWithFileUseSiteTarget2() throws Exception { + runTest("idea/testData/quickfix/deprecatedSymbolUsage/classUsages/annotationWithFileUseSiteTarget2.kt"); + } + + @TestMetadata("annotationWithFileUseSiteTarget3.kt") + public void testAnnotationWithFileUseSiteTarget3() throws Exception { + runTest("idea/testData/quickfix/deprecatedSymbolUsage/classUsages/annotationWithFileUseSiteTarget3.kt"); + } + + @TestMetadata("annotationWithGetUseSiteTarget1.kt") + public void testAnnotationWithGetUseSiteTarget1() throws Exception { + runTest("idea/testData/quickfix/deprecatedSymbolUsage/classUsages/annotationWithGetUseSiteTarget1.kt"); + } + + @TestMetadata("annotationWithGetUseSiteTarget2.kt") + public void testAnnotationWithGetUseSiteTarget2() throws Exception { + runTest("idea/testData/quickfix/deprecatedSymbolUsage/classUsages/annotationWithGetUseSiteTarget2.kt"); + } + + @TestMetadata("annotationWithGetUseSiteTarget3.kt") + public void testAnnotationWithGetUseSiteTarget3() throws Exception { + runTest("idea/testData/quickfix/deprecatedSymbolUsage/classUsages/annotationWithGetUseSiteTarget3.kt"); + } + @TestMetadata("constructorUsage1.kt") public void testConstructorUsage1() throws Exception { runTest("idea/testData/quickfix/deprecatedSymbolUsage/classUsages/constructorUsage1.kt");