Replace with: do not remove annotation use-site targets

This commit is contained in:
Toshiaki Kameyama
2020-03-08 22:59:46 +09:00
committed by Dmitry Gridin
parent f573719cc1
commit 06bd620dd6
14 changed files with 136 additions and 1 deletions
@@ -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)
}
}
@@ -0,0 +1,3 @@
// "Replace with 'OptIn(*markerClass)'" "true"
// WITH_RUNTIME
@file:<caret>UseExperimental
@@ -0,0 +1,3 @@
// "Replace with 'OptIn(*markerClass)'" "true"
// WITH_RUNTIME
@file:<caret>OptIn()
@@ -0,0 +1,3 @@
// "Replace with 'OptIn(*markerClass)'" "true"
// WITH_RUNTIME
@file:<caret>UseExperimental()
@@ -0,0 +1,3 @@
// "Replace with 'OptIn(*markerClass)'" "true"
// WITH_RUNTIME
@file:OptIn()
@@ -0,0 +1,6 @@
// "Replace with 'OptIn(*markerClass)'" "true"
// WITH_RUNTIME
@file:<caret>UseExperimental(Foo::class, Bar::class)
annotation class Foo
annotation class Bar
@@ -0,0 +1,6 @@
// "Replace with 'OptIn(*markerClass)'" "true"
// WITH_RUNTIME
@file:OptIn(Foo::class, Bar::class)
annotation class Foo
annotation class Bar
@@ -0,0 +1,12 @@
// "Replace with 'Bar'" "true"
class Test {
@get:<caret>Foo
val s: String = ""
}
@Deprecated("Replace with Bar", ReplaceWith("Bar"))
@Target(AnnotationTarget.PROPERTY_GETTER)
annotation class Foo
@Target(AnnotationTarget.PROPERTY_GETTER)
annotation class Bar
@@ -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
@@ -0,0 +1,12 @@
// "Replace with 'Bar()'" "true"
class Test {
@get:<caret>Foo
val s: String = ""
}
@Deprecated("Replace with Bar", ReplaceWith("Bar()"))
@Target(AnnotationTarget.PROPERTY_GETTER)
annotation class Foo
@Target(AnnotationTarget.PROPERTY_GETTER)
annotation class Bar
@@ -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
@@ -0,0 +1,12 @@
// "Replace with 'Bar(i)'" "true"
class Test {
@get:<caret>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)
@@ -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)
@@ -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");