KT-27445: Add QuickFix for DEPRECATED_JAVA_ANNOTATION compiler warning
This commit is contained in:
committed by
Mikhail Glukhikh
parent
570c770d58
commit
374eec04d4
@@ -0,0 +1,62 @@
|
|||||||
|
package org.jetbrains.kotlin.idea.quickfix
|
||||||
|
|
||||||
|
import com.intellij.codeInsight.intention.IntentionAction
|
||||||
|
import com.intellij.openapi.editor.Editor
|
||||||
|
import com.intellij.openapi.project.Project
|
||||||
|
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
||||||
|
import org.jetbrains.kotlin.load.java.components.JavaAnnotationMapper
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
import org.jetbrains.kotlin.psi.*
|
||||||
|
import org.jetbrains.kotlin.resolve.ImportPath
|
||||||
|
import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm
|
||||||
|
|
||||||
|
internal class DeprecatedJavaAnnotationFix(element: KtAnnotationEntry,
|
||||||
|
private val annotationFqName: FqName,
|
||||||
|
private val arguments: List<KtValueArgument>) : KotlinQuickFixAction<KtAnnotationEntry>(element) {
|
||||||
|
override fun getFamilyName() = "Replace Annotation"
|
||||||
|
override fun getText(): String = "Replace annotation with ${annotationFqName.asString()}"
|
||||||
|
|
||||||
|
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||||
|
val element = element ?: return
|
||||||
|
|
||||||
|
val psiFactory = KtPsiFactory(project)
|
||||||
|
|
||||||
|
val argumentString = if(arguments.isEmpty()) {
|
||||||
|
""
|
||||||
|
} else {
|
||||||
|
"("+ arguments.joinToString(",") { it.text } + ")"
|
||||||
|
}
|
||||||
|
|
||||||
|
element.replace(psiFactory.createAnnotationEntry("@" + annotationFqName.shortName() + argumentString))
|
||||||
|
|
||||||
|
for ((java, kotlin) in JavaAnnotationMapper.javaToKotlinNameMap) {
|
||||||
|
if (kotlin == annotationFqName) {
|
||||||
|
val oldImport = file.importDirectives.find { it -> it.importedFqName == java } ?: return
|
||||||
|
oldImport.delete()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
file.importList?.add(psiFactory.createImportDirective(ImportPath(annotationFqName, false, null)))
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object Factory : KotlinSingleIntentionActionFactory() {
|
||||||
|
override fun createAction(diagnostic: Diagnostic): IntentionAction? {
|
||||||
|
val castedDiagnostic = ErrorsJvm.DEPRECATED_JAVA_ANNOTATION.cast(diagnostic)
|
||||||
|
|
||||||
|
val updatedAnnotation = castedDiagnostic.a as? FqName ?: return null
|
||||||
|
|
||||||
|
val entry = diagnostic.psiElement as? KtAnnotationEntry ?: return null
|
||||||
|
|
||||||
|
val arguments = mutableListOf<KtValueArgument>()
|
||||||
|
entry.valueArguments.forEach {
|
||||||
|
(it as KtValueArgument).children.forEach { child ->
|
||||||
|
arguments.add(child.context as KtValueArgument)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return DeprecatedJavaAnnotationFix(entry, updatedAnnotation, arguments)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -449,6 +449,7 @@ class QuickFixRegistrar : QuickFixContributor {
|
|||||||
UNDERSCORE_IS_RESERVED.registerFactory(RenameUnderscoreFix)
|
UNDERSCORE_IS_RESERVED.registerFactory(RenameUnderscoreFix)
|
||||||
|
|
||||||
DEPRECATED_TYPE_PARAMETER_SYNTAX.registerFactory(MigrateTypeParameterListFix)
|
DEPRECATED_TYPE_PARAMETER_SYNTAX.registerFactory(MigrateTypeParameterListFix)
|
||||||
|
ErrorsJvm.DEPRECATED_JAVA_ANNOTATION.registerFactory(DeprecatedJavaAnnotationFix)
|
||||||
|
|
||||||
UNRESOLVED_REFERENCE.registerFactory(KotlinAddOrderEntryActionFactory)
|
UNRESOLVED_REFERENCE.registerFactory(KotlinAddOrderEntryActionFactory)
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
// "Replace annotation with kotlin.annotation.Retention" "true"
|
||||||
|
// ERROR: Type mismatch: inferred type is RetentionPolicy but AnnotationRetention was expected
|
||||||
|
|
||||||
|
import java.lang.annotation.RetentionPolicy
|
||||||
|
import java.lang.annotation.Retention
|
||||||
|
|
||||||
|
@Retention<caret>(RetentionPolicy.SOURCE)
|
||||||
|
annotation class Foo
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
// "Replace annotation with kotlin.annotation.Retention" "true"
|
||||||
|
// ERROR: Type mismatch: inferred type is RetentionPolicy but AnnotationRetention was expected
|
||||||
|
|
||||||
|
import java.lang.annotation.RetentionPolicy
|
||||||
|
import kotlin.annotation.Retention
|
||||||
|
|
||||||
|
@Retention<caret>(RetentionPolicy.SOURCE)
|
||||||
|
annotation class Foo
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
// "Replace annotation with kotlin.annotation.MustBeDocumented" "true"
|
||||||
|
|
||||||
|
import java.lang.annotation.Documented
|
||||||
|
|
||||||
|
@Documented<caret>
|
||||||
|
annotation class Foo
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
// "Replace annotation with kotlin.annotation.MustBeDocumented" "true"
|
||||||
|
|
||||||
|
import kotlin.annotation.MustBeDocumented
|
||||||
|
|
||||||
|
@MustBeDocumented<caret>
|
||||||
|
annotation class Foo
|
||||||
+13
@@ -2301,6 +2301,19 @@ public class QuickFixMultiFileTestGenerated extends AbstractQuickFixMultiFileTes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("idea/testData/quickfix/deprecatedJavaAnnotation")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class DeprecatedJavaAnnotation extends AbstractQuickFixMultiFileTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest(this::doTestWithExtraFile, TargetBackend.ANY, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInDeprecatedJavaAnnotation() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/deprecatedJavaAnnotation"), Pattern.compile("^(\\w+)\\.((before\\.Main\\.\\w+)|(test))$"), TargetBackend.ANY, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("idea/testData/quickfix/deprecatedSymbolUsage")
|
@TestMetadata("idea/testData/quickfix/deprecatedSymbolUsage")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
|||||||
@@ -5251,6 +5251,29 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("idea/testData/quickfix/deprecatedJavaAnnotation")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class DeprecatedJavaAnnotation extends AbstractQuickFixTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInDeprecatedJavaAnnotation() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/deprecatedJavaAnnotation"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), TargetBackend.ANY, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("withArgument.kt")
|
||||||
|
public void testWithArgument() throws Exception {
|
||||||
|
runTest("idea/testData/quickfix/deprecatedJavaAnnotation/withArgument.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("withoutArguments.kt")
|
||||||
|
public void testWithoutArguments() throws Exception {
|
||||||
|
runTest("idea/testData/quickfix/deprecatedJavaAnnotation/withoutArguments.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("idea/testData/quickfix/deprecatedSymbolUsage")
|
@TestMetadata("idea/testData/quickfix/deprecatedSymbolUsage")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
|||||||
Reference in New Issue
Block a user