"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 problemDescriptors = arrayListOf<ProblemDescriptor>()
|
||||||
|
|
||||||
val importsToRemove = file.importDirectives.filter { DeprecatedSymbolUsageFix.isImportToBeRemoved(it) }
|
val importsToRemove = DeprecatedSymbolUsageFix.importDirectivesToBeRemoved(file)
|
||||||
for (import in importsToRemove) {
|
for (import in importsToRemove) {
|
||||||
val removeImportFix = RemoveImportFix(import)
|
val removeImportFix = RemoveImportFix(import)
|
||||||
val problemDescriptor = createProblemDescriptor(import, removeImportFix.text, listOf(removeImportFix), file, manager)
|
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.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.diagnostics.Diagnostic
|
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
||||||
import org.jetbrains.kotlin.idea.KotlinBundle
|
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.codeInliner.UsageReplacementStrategy
|
||||||
import org.jetbrains.kotlin.idea.core.moveCaret
|
import org.jetbrains.kotlin.idea.core.moveCaret
|
||||||
import org.jetbrains.kotlin.idea.core.targetDescriptors
|
import org.jetbrains.kotlin.idea.core.targetDescriptors
|
||||||
import org.jetbrains.kotlin.idea.quickfix.CleanupFix
|
import org.jetbrains.kotlin.idea.quickfix.CleanupFix
|
||||||
import org.jetbrains.kotlin.idea.quickfix.KotlinSingleIntentionActionFactory
|
import org.jetbrains.kotlin.idea.quickfix.KotlinSingleIntentionActionFactory
|
||||||
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.psi.KtImportDirective
|
import org.jetbrains.kotlin.psi.KtImportDirective
|
||||||
import org.jetbrains.kotlin.psi.KtReferenceExpression
|
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.calls.callUtil.getCalleeExpressionIfAny
|
||||||
|
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||||
|
|
||||||
class DeprecatedSymbolUsageFix(
|
class DeprecatedSymbolUsageFix(
|
||||||
element: KtReferenceExpression,
|
element: KtReferenceExpression,
|
||||||
@@ -55,7 +60,23 @@ class DeprecatedSymbolUsageFix(
|
|||||||
return DeprecatedSymbolUsageFix(referenceExpression, replacement)
|
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
|
if (import.isAllUnder) return false
|
||||||
|
|
||||||
val targetDescriptors = import.targetDescriptors()
|
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
|
import org.junit.runner.RunWith
|
||||||
|
|
||||||
@RunWith(JUnit3WithIdeaConfigurationRunner::class)
|
@RunWith(JUnit3WithIdeaConfigurationRunner::class)
|
||||||
class KotlinCleanupInspectionTest() : KotlinLightCodeInsightFixtureTestCase() {
|
class KotlinCleanupInspectionTest : KotlinLightCodeInsightFixtureTestCase() {
|
||||||
override fun getTestDataPath(): String = PluginTestCaseBase.getTestDataPathBase() + "/inspections/cleanup"
|
override fun getTestDataPath(): String = PluginTestCaseBase.getTestDataPathBase() + "/inspections/cleanup"
|
||||||
|
|
||||||
override fun getProjectDescriptor(): LightProjectDescriptor = KotlinWithJdkAndRuntimeLightProjectDescriptor.INSTANCE
|
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(KotlinCleanupInspection::class.java)
|
||||||
myFixture.enableInspections(SortModifiersInspection::class.java)
|
myFixture.enableInspections(SortModifiersInspection::class.java)
|
||||||
myFixture.enableInspections(RedundantModalityModifierInspection::class.java)
|
myFixture.enableInspections(RedundantModalityModifierInspection::class.java)
|
||||||
myFixture.configureByFiles(*files)
|
myFixture.configureByFiles(*files.map { "$dir/$it" }.toTypedArray())
|
||||||
|
|
||||||
val project = myFixture.project
|
val project = myFixture.project
|
||||||
val managerEx = InspectionManager.getInstance(project)
|
val managerEx = InspectionManager.getInstance(project)
|
||||||
@@ -35,10 +35,19 @@ class KotlinCleanupInspectionTest() : KotlinLightCodeInsightFixtureTestCase() {
|
|||||||
val profile = InspectionProjectProfileManager.getInstance(project).currentProfile
|
val profile = InspectionProjectProfileManager.getInstance(project).currentProfile
|
||||||
globalContext.codeCleanup(analysisScope, profile, "Cleanup", null, true)
|
globalContext.codeCleanup(analysisScope, profile, "Cleanup", null, true)
|
||||||
|
|
||||||
myFixture.checkResultByFile(result)
|
myFixture.checkResultByFile("$dir/$result")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun testCleanup() {
|
fun testBasic() {
|
||||||
doTest("cleanup.kt.after", "cleanup.kt", "JavaAnn.java", "deprecatedSymbols.kt")
|
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