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.project.Project
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget
|
||||
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.idea.core.ShortenReferences
|
||||
import org.jetbrains.kotlin.idea.references.resolveMainReferenceToDescriptors
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.containingClass
|
||||
@@ -28,9 +30,10 @@ object RestrictedRetentionForExpressionAnnotationFactory : KotlinIntentionAction
|
||||
val containingClass = annotationEntry.containingClass() ?: return emptyList()
|
||||
val retentionAnnotation = containingClass.annotation(KotlinBuiltIns.FQ_NAMES.retention)
|
||||
val targetAnnotation = containingClass.annotation(KotlinBuiltIns.FQ_NAMES.target)
|
||||
val expressionTargetArgument = if (targetAnnotation != null) findExpressionTargetArgument(targetAnnotation) else null
|
||||
|
||||
return listOfNotNull(
|
||||
if (targetAnnotation != null) RemoveExpressionTargetFix(targetAnnotation) else null,
|
||||
if (expressionTargetArgument != null) RemoveExpressionTargetFix(expressionTargetArgument) else null,
|
||||
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) {
|
||||
override fun getText() = "Add SOURCE retention"
|
||||
|
||||
@@ -78,16 +95,23 @@ object RestrictedRetentionForExpressionAnnotationFactory : KotlinIntentionAction
|
||||
}
|
||||
}
|
||||
|
||||
private class RemoveExpressionTargetFix(targetAnnotation: KtAnnotationEntry) :
|
||||
KotlinQuickFixAction<KtAnnotationEntry>(targetAnnotation) {
|
||||
private class RemoveExpressionTargetFix(expressionTargetArgument: KtValueArgument) :
|
||||
KotlinQuickFixAction<KtValueArgument>(expressionTargetArgument) {
|
||||
|
||||
override fun getText() = "Remove EXPRESSION target"
|
||||
|
||||
override fun getFamilyName() = text
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val targetAnnotation = element ?: return
|
||||
targetAnnotation.delete()
|
||||
val expressionTargetArgument = element ?: return
|
||||
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");
|
||||
}
|
||||
|
||||
@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")
|
||||
public void testNoRetention() throws Exception {
|
||||
runTest("idea/testData/quickfix/restrictedRetentionForExpressionAnnotation/removeExpressionTarget/noRetention.kt");
|
||||
|
||||
Reference in New Issue
Block a user