[jvm] Use hinted visitor adapter in MustAlreadyBeRemovedApiInspection

GitOrigin-RevId: 188b2ca5b693dd8713971c76265b05a73f2a5afc
This commit is contained in:
Bart van Helvert
2023-03-29 10:02:29 +02:00
committed by intellij-monorepo-bot
parent b26d62ec6e
commit e1569053b2
6 changed files with 84 additions and 92 deletions

View File

@@ -6,7 +6,7 @@ import com.intellij.codeInspection.options.OptPane
import com.intellij.codeInspection.options.OptPane.pane
import com.intellij.codeInspection.options.OptPane.string
import com.intellij.psi.PsiElementVisitor
import com.intellij.uast.UastVisitorAdapter
import com.intellij.uast.UastHintedVisitorAdapter
import com.intellij.util.text.VersionComparatorUtil
import org.jetbrains.annotations.ApiStatus
import org.jetbrains.uast.UAnnotated
@@ -19,19 +19,21 @@ import org.jetbrains.uast.visitor.AbstractUastNonRecursiveVisitor
* Reports declarations (classes, methods, fields) marked with [ApiStatus.ScheduledForRemoval] annotation
* that must already be removed. [ApiStatus.ScheduledForRemoval.inVersion] value is compared with "current" version.
*/
class MustAlreadyBeRemovedApiInspection : LocalInspectionTool() {
private companion object {
private val SCHEDULED_FOR_REMOVAL_ANNOTATION_NAME = ApiStatus.ScheduledForRemoval::class.java.canonicalName
}
class MustAlreadyBeRemovedApiInspection : AbstractBaseUastLocalInspectionTool() {
var currentVersion: String = ""
override fun getOptionsPane(): OptPane = pane(string("currentVersion", JvmAnalysisBundle.message("current.version")))
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor {
if (currentVersion.isEmpty() || !AnnotatedApiUsageUtil.canAnnotationBeUsedInFile(SCHEDULED_FOR_REMOVAL_ANNOTATION_NAME, holder.file)) {
return PsiElementVisitor.EMPTY_VISITOR
}
return UastVisitorAdapter(MustAlreadyBeRemovedApiVisitor(holder, currentVersion), true)
return UastHintedVisitorAdapter.create(
holder.file.language,
MustAlreadyBeRemovedApiVisitor(holder, currentVersion),
arrayOf(UDeclaration::class.java),
true
)
}
private class MustAlreadyBeRemovedApiVisitor(
@@ -67,6 +69,8 @@ class MustAlreadyBeRemovedApiInspection : LocalInspectionTool() {
}
}
override fun getOptionsPane(): OptPane = pane(string("currentVersion", JvmAnalysisBundle.message("current.version")))
private companion object {
private val SCHEDULED_FOR_REMOVAL_ANNOTATION_NAME = ApiStatus.ScheduledForRemoval::class.java.canonicalName
}
}

View File

@@ -1,33 +0,0 @@
package test;
import org.jetbrains.annotations.ApiStatus;
@ApiStatus.ScheduledForRemoval(inVersion = "2.0")
@Deprecated
class <error descr="API must have been removed in version 2.0 but the current version is 3.0">Warnings</error> {
@ApiStatus.ScheduledForRemoval(inVersion = "2.0")
@Deprecated
public String <error descr="API must have been removed in version 2.0 but the current version is 3.0">field</error>;
@ApiStatus.ScheduledForRemoval(inVersion = "2.0")
@Deprecated
public void <error descr="API must have been removed in version 2.0 but the current version is 3.0">method</error>() {
}
}
//No warnings should be produced.
@Deprecated
@ApiStatus.ScheduledForRemoval(inVersion = "5.0")
class NoWarnings {
@Deprecated
@ApiStatus.ScheduledForRemoval(inVersion = "5.0")
public String field;
@Deprecated
@ApiStatus.ScheduledForRemoval(inVersion = "5.0")
public void method() {
}
}

View File

@@ -1,16 +1,43 @@
package com.intellij.codeInspection.tests.java
import com.intellij.codeInspection.tests.JvmLanguage
import com.intellij.codeInspection.tests.MustAlreadyBeRemovedApiInspectionTestBase
import com.intellij.jvm.analysis.JavaJvmAnalysisTestUtil
import com.intellij.testFramework.TestDataPath
private const val inspectionPath = "/codeInspection/mustAlreadyBeRemovedApi"
@TestDataPath("\$CONTENT_ROOT/testData$inspectionPath")
class JavaMustAlreadyBeRemovedApiInspectionTest : MustAlreadyBeRemovedApiInspectionTestBase() {
override fun getBasePath() = JavaJvmAnalysisTestUtil.TEST_DATA_PROJECT_RELATIVE_BASE_PATH + inspectionPath
fun `test APIs must have been removed`() {
myFixture.testHighlighting("outdatedApi.java")
inspection.currentVersion = "3.0"
myFixture.testHighlighting(JvmLanguage.JAVA, """
import org.jetbrains.annotations.ApiStatus;
@ApiStatus.ScheduledForRemoval(inVersion = "2.0")
@Deprecated
class <error descr="API must have been removed in version 2.0 but the current version is 3.0">Warnings</error> {
@ApiStatus.ScheduledForRemoval(inVersion = "2.0")
@Deprecated
public String <error descr="API must have been removed in version 2.0 but the current version is 3.0">field</error>;
@ApiStatus.ScheduledForRemoval(inVersion = "2.0")
@Deprecated
public void <error descr="API must have been removed in version 2.0 but the current version is 3.0">method</error>() {
}
}
//No warnings should be produced.
@Deprecated
@ApiStatus.ScheduledForRemoval(inVersion = "5.0")
class NoWarnings {
@Deprecated
@ApiStatus.ScheduledForRemoval(inVersion = "5.0")
public String field;
@Deprecated
@ApiStatus.ScheduledForRemoval(inVersion = "5.0")
public void method() {
}
}
""".trimIndent())
}
}

View File

@@ -1,33 +0,0 @@
package test
import org.jetbrains.annotations.ApiStatus
@ApiStatus.ScheduledForRemoval(inVersion = "2.0")
@Deprecated("")
class <error descr="API must have been removed in version 2.0 but the current version is 3.0">Warnings</error> {
@ApiStatus.ScheduledForRemoval(inVersion = "2.0")
@Deprecated("")
var <error descr="API must have been removed in version 2.0 but the current version is 3.0">field</error>: String? = null
@ApiStatus.ScheduledForRemoval(inVersion = "2.0")
@Deprecated("")
fun <error descr="API must have been removed in version 2.0 but the current version is 3.0">method</error>() {
}
}
//No warnings should be produced.
@Deprecated("")
@ApiStatus.ScheduledForRemoval(inVersion = "5.0")
class NoWarnings {
@Deprecated("")
@ApiStatus.ScheduledForRemoval(inVersion = "5.0")
var field: String? = null
@Deprecated("")
@ApiStatus.ScheduledForRemoval(inVersion = "5.0")
fun method() {
}
}

View File

@@ -1,16 +1,43 @@
package com.intellij.codeInspection.tests.kotlin
import com.intellij.codeInspection.tests.JvmLanguage
import com.intellij.codeInspection.tests.MustAlreadyBeRemovedApiInspectionTestBase
import com.intellij.jvm.analysis.KotlinJvmAnalysisTestUtil
import com.intellij.testFramework.TestDataPath
private const val inspectionPath = "/codeInspection/mustAlreadyBeRemovedApi"
@TestDataPath("\$CONTENT_ROOT/testData$inspectionPath")
class KotlinMustAlreadyBeRemovedApiInspectionTest : MustAlreadyBeRemovedApiInspectionTestBase() {
override fun getBasePath() = KotlinJvmAnalysisTestUtil.TEST_DATA_PROJECT_RELATIVE_BASE_PATH + inspectionPath
fun `test APIs must have been removed`() {
myFixture.testHighlighting("outdatedApi.kt")
inspection.currentVersion = "3.0"
myFixture.testHighlighting(JvmLanguage.KOTLIN, """
import org.jetbrains.annotations.ApiStatus
@ApiStatus.ScheduledForRemoval(inVersion = "2.0")
@Deprecated("")
class <error descr="API must have been removed in version 2.0 but the current version is 3.0">Warnings</error> {
@ApiStatus.ScheduledForRemoval(inVersion = "2.0")
@Deprecated("")
var <error descr="API must have been removed in version 2.0 but the current version is 3.0">field</error>: String? = null
@ApiStatus.ScheduledForRemoval(inVersion = "2.0")
@Deprecated("")
fun <error descr="API must have been removed in version 2.0 but the current version is 3.0">method</error>() {
}
}
//No warnings should be produced.
@Deprecated("")
@ApiStatus.ScheduledForRemoval(inVersion = "5.0")
class NoWarnings {
@Deprecated("")
@ApiStatus.ScheduledForRemoval(inVersion = "5.0")
var field: String? = null
@Deprecated("")
@ApiStatus.ScheduledForRemoval(inVersion = "5.0")
fun method() {
}
}
""".trimIndent())
}
}

View File

@@ -11,7 +11,7 @@ import org.jetbrains.annotations.ApiStatus
import java.io.File
abstract class MustAlreadyBeRemovedApiInspectionTestBase : JvmInspectionTestBase() {
override val inspection = MustAlreadyBeRemovedApiInspection().apply { currentVersion = "3.0" }
override val inspection: MustAlreadyBeRemovedApiInspection = MustAlreadyBeRemovedApiInspection()
@Suppress("DuplicatedCode")
override fun getProjectDescriptor(): LightProjectDescriptor = object : ProjectDescriptor(sdkLevel) {