Fix RemoveExpressionTargetFix and don't remove the whole annotation (KT-25574)
This commit is contained in:
+29
-5
@@ -9,9 +9,11 @@ import com.intellij.codeInsight.intention.IntentionAction
|
|||||||
import com.intellij.openapi.editor.Editor
|
import com.intellij.openapi.editor.Editor
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
|
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget
|
||||||
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||||
import org.jetbrains.kotlin.idea.core.ShortenReferences
|
import org.jetbrains.kotlin.idea.core.ShortenReferences
|
||||||
|
import org.jetbrains.kotlin.idea.references.resolveMainReferenceToDescriptors
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.containingClass
|
import org.jetbrains.kotlin.psi.psiUtil.containingClass
|
||||||
@@ -28,9 +30,10 @@ object RestrictedRetentionForExpressionAnnotationFactory : KotlinIntentionAction
|
|||||||
val containingClass = annotationEntry.containingClass() ?: return emptyList()
|
val containingClass = annotationEntry.containingClass() ?: return emptyList()
|
||||||
val retentionAnnotation = containingClass.annotation(KotlinBuiltIns.FQ_NAMES.retention)
|
val retentionAnnotation = containingClass.annotation(KotlinBuiltIns.FQ_NAMES.retention)
|
||||||
val targetAnnotation = containingClass.annotation(KotlinBuiltIns.FQ_NAMES.target)
|
val targetAnnotation = containingClass.annotation(KotlinBuiltIns.FQ_NAMES.target)
|
||||||
|
val expressionTargetArgument = if (targetAnnotation != null) findExpressionTargetArgument(targetAnnotation) else null
|
||||||
|
|
||||||
return listOfNotNull(
|
return listOfNotNull(
|
||||||
if (targetAnnotation != null) RemoveExpressionTargetFix(targetAnnotation) else null,
|
if (expressionTargetArgument != null) RemoveExpressionTargetFix(expressionTargetArgument) else null,
|
||||||
if (retentionAnnotation == null) AddSourceRetentionFix(containingClass) else ChangeRetentionToSourceFix(retentionAnnotation)
|
if (retentionAnnotation == null) AddSourceRetentionFix(containingClass) else ChangeRetentionToSourceFix(retentionAnnotation)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -42,6 +45,20 @@ object RestrictedRetentionForExpressionAnnotationFactory : KotlinIntentionAction
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun findExpressionTargetArgument(targetAnnotation: KtAnnotationEntry): KtValueArgument? {
|
||||||
|
val valueArgumentList = targetAnnotation.valueArgumentList ?: return null
|
||||||
|
if (targetAnnotation.lambdaArguments.isNotEmpty()) return null
|
||||||
|
|
||||||
|
for (valueArgument in valueArgumentList.arguments) {
|
||||||
|
val argumentExpression = valueArgument.getArgumentExpression() ?: continue
|
||||||
|
if (argumentExpression.text.contains(KotlinTarget.EXPRESSION.toString())) {
|
||||||
|
return valueArgument
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
private class AddSourceRetentionFix(element: KtClass) : KotlinQuickFixAction<KtClass>(element) {
|
private class AddSourceRetentionFix(element: KtClass) : KotlinQuickFixAction<KtClass>(element) {
|
||||||
override fun getText() = "Add SOURCE retention"
|
override fun getText() = "Add SOURCE retention"
|
||||||
|
|
||||||
@@ -78,16 +95,23 @@ object RestrictedRetentionForExpressionAnnotationFactory : KotlinIntentionAction
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class RemoveExpressionTargetFix(targetAnnotation: KtAnnotationEntry) :
|
private class RemoveExpressionTargetFix(expressionTargetArgument: KtValueArgument) :
|
||||||
KotlinQuickFixAction<KtAnnotationEntry>(targetAnnotation) {
|
KotlinQuickFixAction<KtValueArgument>(expressionTargetArgument) {
|
||||||
|
|
||||||
override fun getText() = "Remove EXPRESSION target"
|
override fun getText() = "Remove EXPRESSION target"
|
||||||
|
|
||||||
override fun getFamilyName() = text
|
override fun getFamilyName() = text
|
||||||
|
|
||||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||||
val targetAnnotation = element ?: return
|
val expressionTargetArgument = element ?: return
|
||||||
targetAnnotation.delete()
|
val argumentList = expressionTargetArgument.parent as? KtValueArgumentList ?: return
|
||||||
|
|
||||||
|
if (argumentList.arguments.size == 1) {
|
||||||
|
val annotation = argumentList.parent as? KtAnnotationEntry ?: return
|
||||||
|
annotation.delete()
|
||||||
|
} else {
|
||||||
|
argumentList.removeArgument(expressionTargetArgument)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
// "Remove EXPRESSION target" "true"
|
||||||
|
import kotlin.annotation.AnnotationTarget.*
|
||||||
|
|
||||||
|
<caret>@Retention
|
||||||
|
@Target(FIELD, EXPRESSION, PROPERTY)
|
||||||
|
annotation class Ann
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
// "Remove EXPRESSION target" "true"
|
||||||
|
import kotlin.annotation.AnnotationTarget.*
|
||||||
|
|
||||||
|
<caret>@Retention
|
||||||
|
@Target(FIELD, PROPERTY)
|
||||||
|
annotation class Ann
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
// "Remove EXPRESSION target" "true"
|
||||||
|
<caret>@Retention
|
||||||
|
@Target(AnnotationTarget.FIELD, AnnotationTarget.EXPRESSION, AnnotationTarget.PROPERTY)
|
||||||
|
annotation class Ann
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
// "Remove EXPRESSION target" "true"
|
||||||
|
<caret>@Retention
|
||||||
|
@Target(AnnotationTarget.FIELD, AnnotationTarget.PROPERTY)
|
||||||
|
annotation class Ann
|
||||||
@@ -10970,6 +10970,16 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
|
|||||||
runTest("idea/testData/quickfix/restrictedRetentionForExpressionAnnotation/removeExpressionTarget/emptyRetention2.kt");
|
runTest("idea/testData/quickfix/restrictedRetentionForExpressionAnnotation/removeExpressionTarget/emptyRetention2.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("multipleTargets.kt")
|
||||||
|
public void testMultipleTargets() throws Exception {
|
||||||
|
runTest("idea/testData/quickfix/restrictedRetentionForExpressionAnnotation/removeExpressionTarget/multipleTargets.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("multipleTargetsImported.kt")
|
||||||
|
public void testMultipleTargetsImported() throws Exception {
|
||||||
|
runTest("idea/testData/quickfix/restrictedRetentionForExpressionAnnotation/removeExpressionTarget/multipleTargetsImported.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("noRetention.kt")
|
@TestMetadata("noRetention.kt")
|
||||||
public void testNoRetention() throws Exception {
|
public void testNoRetention() throws Exception {
|
||||||
runTest("idea/testData/quickfix/restrictedRetentionForExpressionAnnotation/removeExpressionTarget/noRetention.kt");
|
runTest("idea/testData/quickfix/restrictedRetentionForExpressionAnnotation/removeExpressionTarget/noRetention.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user