[spring] IDEA-380087 API versioning: provide an inspection and a quick-fix to configure API versioning in tests

Relates to IDEA-381232

(cherry picked from commit 8b6e24472a4cbe1362e52e9124d48e5feac6c64e)

IJ-MR-179458

GitOrigin-RevId: 1e744850bd2833e0280fedd0ea6d957859736b19
This commit is contained in:
Daniil Tsarev
2025-10-22 12:52:33 +02:00
committed by intellij-monorepo-bot
parent 77f8bb12e5
commit 9bad113cab
3 changed files with 90 additions and 0 deletions

View File

@@ -79,6 +79,12 @@ abstract class KotlinUastBaseCodeGenerationPlugin : UastCodeGenerationPlugin {
return shortenReference(sourcePsi).toUElementOfType()
}
override fun shortenReference(uDeclaration: UDeclaration): UDeclaration? {
val sourcePsi = uDeclaration.sourcePsi ?: return null
if (sourcePsi !is KtElement) return null
return shortenReference(sourcePsi).toUElementOfType()
}
abstract fun shortenReference(sourcePsi: KtElement): PsiElement?
override fun importMemberOnDemand(reference: UQualifiedReferenceExpression): UExpression? {
@@ -296,6 +302,16 @@ abstract class KotlinUastElementFactory(project: Project) : UastElementFactory {
return stringBuilder.toString()
}
override fun createIntegerConstantExpression(
integer: Int,
context: PsiElement?
): UExpression? {
return when (val literalExpr = psiFactory(context).createExpression("$integer")) {
is KtConstantExpression -> KotlinULiteralExpression(literalExpr, null)
else -> null
}
}
override fun createLongConstantExpression(long: Long, context: PsiElement?): UExpression? {
return when (val literalExpr = psiFactory(context).createExpression(long.toString() + "L")) {
is KtConstantExpression -> KotlinULiteralExpression(literalExpr, null)
@@ -312,6 +328,21 @@ abstract class KotlinUastElementFactory(project: Project) : UastElementFactory {
return psiFactory(context).createComment(text).toUElementOfType()!!
}
override fun createClass(className: String, extends: List<String>, implements: List<String>, context: PsiElement): UClass? {
val extendsPart = if (extends.size + implements.size >= 1)
(extends + implements).joinToString(", ", " : ")
else
""
val classText = """
class $className$extendsPart {
}
""".trimIndent()
val ktClass = psiFactory(context).createClass(classText)
return ktClass.toUElement(UClass::class.java)
}
/*override*/ fun createIntLiteral(value: Int, context: PsiElement?): ULiteralExpression {
return psiFactory(context).createExpression(value.toString()).toUElementOfType()!!
}

View File

@@ -70,6 +70,10 @@ interface UastCodeGenerationPlugin {
*/
fun shortenReference(reference: UReferenceExpression): UReferenceExpression?
fun shortenReference(uDeclaration: UDeclaration): UDeclaration? {
throw NotImplementedError()
}
/**
* Import the qualifier of the specified element as an on demand import (star import).
*
@@ -211,11 +215,22 @@ interface UastElementFactory {
fun createStringLiteralExpression(text: String, context: PsiElement?): UExpression?
fun createIntegerConstantExpression(integer: Int, context: PsiElement?): UExpression? {
throw NotImplementedError()
}
fun createLongConstantExpression(long: Long, context: PsiElement?): UExpression?
fun createNullLiteral(context: PsiElement?): ULiteralExpression?
fun createComment(text: String, context: PsiElement?): UComment
fun createClass(className: String,
extends: List<String>,
implements: List<String>,
context: PsiElement): UClass? {
throw NotImplementedError()
}
}
@ApiStatus.Experimental

View File

@@ -3,6 +3,7 @@ package org.jetbrains.uast.java.generate
import com.intellij.codeInsight.BlockUtils
import com.intellij.codeInsight.intention.impl.AddOnDemandStaticImportAction
import com.intellij.ide.highlighter.JavaFileType
import com.intellij.lang.Language
import com.intellij.lang.java.JavaLanguage
import com.intellij.lang.jvm.JvmModifier
@@ -16,6 +17,7 @@ import com.intellij.psi.impl.source.tree.CompositeElement
import com.intellij.psi.impl.source.tree.ElementType
import com.intellij.psi.impl.source.tree.java.PsiLiteralExpressionImpl
import com.intellij.psi.util.*
import com.intellij.util.IncorrectOperationException
import com.intellij.util.asSafely
import com.siyeh.ig.psiutils.CommentTracker
import com.siyeh.ig.psiutils.ParenthesesUtils
@@ -103,6 +105,12 @@ internal class JavaUastCodeGenerationPlugin : UastCodeGenerationPlugin {
return styleManager.shortenClassReferences(sourceReference).toUElementOfType()
}
override fun shortenReference(uDeclaration: UDeclaration): UDeclaration? {
val sourceReference = uDeclaration.sourcePsi ?: return null
val styleManager = JavaCodeStyleManager.getInstance(sourceReference.project)
return styleManager.shortenClassReferences(sourceReference).toUElementOfType()
}
override fun importMemberOnDemand(reference: UQualifiedReferenceExpression): UExpression? {
val source = reference.sourcePsi ?: return null
val (qualifier, selector) = when (source) {
@@ -299,6 +307,13 @@ class JavaUastElementFactory(private val project: Project) : UastElementFactory
return JavaULiteralExpression(literalExpr, null)
}
override fun createIntegerConstantExpression(integer: Int, context: PsiElement?): UExpression? {
return when (val literalExpr = psiFactory.createExpressionFromText("$integer", context)) {
is PsiLiteralExpressionImpl -> JavaULiteralExpression(literalExpr, null)
else -> null
}
}
override fun createLongConstantExpression(long: Long, context: PsiElement?): UExpression? {
return when (val literalExpr = psiFactory.createExpressionFromText(long.toString() + "L", context)) {
is PsiLiteralExpressionImpl -> JavaULiteralExpression(literalExpr, null)
@@ -317,6 +332,35 @@ class JavaUastElementFactory(private val project: Project) : UastElementFactory
return psiFactory.createCommentFromText(text, context).toUElementOfType()!!
}
override fun createClass(className: String, extends: List<String>, implements: List<String>, context: PsiElement): UClass? {
val extendsPart = if (extends.isNotEmpty())
" extends " + extends.joinToString()
else
""
val implementsPart = if (implements.isNotEmpty())
" implements " + implements.joinToString()
else
""
val classText = """
class $className$extendsPart$implementsPart {
}
""".trimIndent()
val aFile = PsiFileFactory.getInstance(context.project)
.createFileFromText("_Dummy_." + JavaFileType.INSTANCE.defaultExtension,
JavaFileType.INSTANCE,
classText) as PsiJavaFile
val classes = aFile.getClasses()
if (classes.size != 1) {
throw IncorrectOperationException("Incorrect class '$classText'")
}
return classes[0].toUElement(UClass::class.java)
}
private class MethodCallUpgradeHelper(val project: Project, val methodCall: PsiMethodCallExpression, val expectedReturnType: PsiType) {
lateinit var resultType: PsiType