"Code Cleanup": don't remove deprecated imports when file has @file:Suppress("DEPRECATION") annotation
#KT-33594 Fixed
This commit is contained in:
committed by
Yan Zhulanow
parent
4a328981c6
commit
cf5a6274e2
@@ -49,7 +49,7 @@ class KotlinCleanupInspection : LocalInspectionTool(), CleanupLocalInspectionToo
|
||||
|
||||
val problemDescriptors = arrayListOf<ProblemDescriptor>()
|
||||
|
||||
val importsToRemove = file.importDirectives.filter { DeprecatedSymbolUsageFix.isImportToBeRemoved(it) }
|
||||
val importsToRemove = DeprecatedSymbolUsageFix.importDirectivesToBeRemoved(file)
|
||||
for (import in importsToRemove) {
|
||||
val removeImportFix = RemoveImportFix(import)
|
||||
val problemDescriptor = createProblemDescriptor(import, removeImportFix.text, listOf(removeImportFix), file, manager)
|
||||
|
||||
+22
-1
@@ -20,16 +20,21 @@ import com.intellij.codeInsight.intention.HighPriorityAction
|
||||
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.diagnostics.Diagnostic
|
||||
import org.jetbrains.kotlin.idea.KotlinBundle
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveToCall
|
||||
import org.jetbrains.kotlin.idea.codeInliner.UsageReplacementStrategy
|
||||
import org.jetbrains.kotlin.idea.core.moveCaret
|
||||
import org.jetbrains.kotlin.idea.core.targetDescriptors
|
||||
import org.jetbrains.kotlin.idea.quickfix.CleanupFix
|
||||
import org.jetbrains.kotlin.idea.quickfix.KotlinSingleIntentionActionFactory
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.KtImportDirective
|
||||
import org.jetbrains.kotlin.psi.KtReferenceExpression
|
||||
import org.jetbrains.kotlin.psi.KtStringTemplateExpression
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getCalleeExpressionIfAny
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||
|
||||
class DeprecatedSymbolUsageFix(
|
||||
element: KtReferenceExpression,
|
||||
@@ -55,7 +60,23 @@ class DeprecatedSymbolUsageFix(
|
||||
return DeprecatedSymbolUsageFix(referenceExpression, replacement)
|
||||
}
|
||||
|
||||
fun isImportToBeRemoved(import: KtImportDirective): Boolean {
|
||||
fun importDirectivesToBeRemoved(file: KtFile): List<KtImportDirective> {
|
||||
if (file.hasAnnotationToSuppressDeprecation()) return emptyList()
|
||||
return file.importDirectives.filter { isImportToBeRemoved(it) }
|
||||
}
|
||||
|
||||
private fun KtFile.hasAnnotationToSuppressDeprecation(): Boolean {
|
||||
val suppressAnnotationEntry = annotationEntries.firstOrNull {
|
||||
it.shortName?.asString() == "Suppress"
|
||||
&& it.resolveToCall()?.resultingDescriptor?.containingDeclaration?.fqNameSafe == KotlinBuiltIns.FQ_NAMES.suppress
|
||||
} ?: return false
|
||||
return suppressAnnotationEntry.valueArguments.any {
|
||||
val text = (it.getArgumentExpression() as? KtStringTemplateExpression)?.entries?.singleOrNull()?.text ?: return@any false
|
||||
text.equals("DEPRECATION", ignoreCase = true)
|
||||
}
|
||||
}
|
||||
|
||||
private fun isImportToBeRemoved(import: KtImportDirective): Boolean {
|
||||
if (import.isAllUnder) return false
|
||||
|
||||
val targetDescriptors = import.targetDescriptors()
|
||||
|
||||
Vendored
Vendored
+6
@@ -0,0 +1,6 @@
|
||||
package bar
|
||||
|
||||
interface I
|
||||
|
||||
@Deprecated("", ReplaceWith("I"))
|
||||
interface Bar : I
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
@file:Suppress("DEPRECATION")
|
||||
|
||||
package foo
|
||||
|
||||
import bar.Bar
|
||||
|
||||
fun foo(x: Bar) {}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
@file:Suppress("DEPRECATION")
|
||||
|
||||
package foo
|
||||
|
||||
import bar.Bar
|
||||
|
||||
fun foo(x: Bar) {}
|
||||
@@ -17,16 +17,16 @@ import org.jetbrains.kotlin.test.JUnit3WithIdeaConfigurationRunner
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(JUnit3WithIdeaConfigurationRunner::class)
|
||||
class KotlinCleanupInspectionTest() : KotlinLightCodeInsightFixtureTestCase() {
|
||||
class KotlinCleanupInspectionTest : KotlinLightCodeInsightFixtureTestCase() {
|
||||
override fun getTestDataPath(): String = PluginTestCaseBase.getTestDataPathBase() + "/inspections/cleanup"
|
||||
|
||||
override fun getProjectDescriptor(): LightProjectDescriptor = KotlinWithJdkAndRuntimeLightProjectDescriptor.INSTANCE
|
||||
|
||||
private fun doTest(result: String, vararg files: String) {
|
||||
private fun doTest(dir: String, result: String, vararg files: String) {
|
||||
myFixture.enableInspections(KotlinCleanupInspection::class.java)
|
||||
myFixture.enableInspections(SortModifiersInspection::class.java)
|
||||
myFixture.enableInspections(RedundantModalityModifierInspection::class.java)
|
||||
myFixture.configureByFiles(*files)
|
||||
myFixture.configureByFiles(*files.map { "$dir/$it" }.toTypedArray())
|
||||
|
||||
val project = myFixture.project
|
||||
val managerEx = InspectionManager.getInstance(project)
|
||||
@@ -35,10 +35,19 @@ class KotlinCleanupInspectionTest() : KotlinLightCodeInsightFixtureTestCase() {
|
||||
val profile = InspectionProjectProfileManager.getInstance(project).currentProfile
|
||||
globalContext.codeCleanup(analysisScope, profile, "Cleanup", null, true)
|
||||
|
||||
myFixture.checkResultByFile(result)
|
||||
myFixture.checkResultByFile("$dir/$result")
|
||||
}
|
||||
|
||||
fun testCleanup() {
|
||||
doTest("cleanup.kt.after", "cleanup.kt", "JavaAnn.java", "deprecatedSymbols.kt")
|
||||
fun testBasic() {
|
||||
doTest("basic", "basic.kt.after", "basic.kt", "JavaAnn.java", "deprecatedSymbols.kt")
|
||||
}
|
||||
|
||||
fun testFileWithAnnotationToSuppressDeprecation() {
|
||||
doTest(
|
||||
"fileWithAnnotationToSuppressDeprecation",
|
||||
"fileWithAnnotationToSuppressDeprecation.kt.after",
|
||||
"fileWithAnnotationToSuppressDeprecation.kt",
|
||||
"deprecatedSymbols.kt"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user