Fix UL-classes test renders and test data
This commit is contained in:
+28
-9
@@ -1,9 +1,29 @@
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
/** should load cls */
|
||||
annotation class Anno(val p: String = "", val x: Array<Anno> = arrayOf(Anno(p="a"), Anno(p="b")))
|
||||
@Target(*[AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.EXPRESSION])
|
||||
annotation class Anno2()
|
||||
|
||||
/** should load cls */
|
||||
@Target(allowedTargets = [AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.EXPRESSION])
|
||||
annotation class Anno3()
|
||||
|
||||
@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.EXPRESSION)
|
||||
annotation class Anno4()
|
||||
|
||||
@Target(*arrayOf(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.EXPRESSION))
|
||||
annotation class Anno5()
|
||||
|
||||
@Target(allowedTargets = arrayOf(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.EXPRESSION))
|
||||
annotation class Anno6()
|
||||
|
||||
annotation class AnnoWithCompanion() {
|
||||
companion object {
|
||||
fun foo() {}
|
||||
@JvmField
|
||||
val x: Int = 42
|
||||
}
|
||||
}
|
||||
|
||||
annotation class Anno(val p: String = "", val x: Array<Anno> = arrayOf(Anno(p = "a"), Anno(p = "b")))
|
||||
@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION,
|
||||
AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.EXPRESSION)
|
||||
@Retention(AnnotationRetention.SOURCE)
|
||||
@@ -11,15 +31,14 @@ annotation class Anno(val p: String = "", val x: Array<Anno> = arrayOf(Anno(p="a
|
||||
@Deprecated("This anno is deprecated, use === instead", ReplaceWith("this === other"))
|
||||
annotation class Fancy
|
||||
|
||||
/** should load cls */
|
||||
annotation class ReplaceWith(val expression: String)
|
||||
|
||||
/** should load cls */
|
||||
annotation class AnnotatedAttribute(@get:Anno val x: String)
|
||||
|
||||
annotation class Deprecated(
|
||||
val message: String,
|
||||
val replaceWith: ReplaceWith = ReplaceWith(""))
|
||||
|
||||
/** should load cls */
|
||||
annotation class Ann(val arg1: KClass<*>, val arg2: KClass<out Any>)
|
||||
|
||||
|
||||
@@ -39,6 +58,6 @@ class Foo @Anno constructor(dependency: MyDependency) {
|
||||
|
||||
@Ann(String::class, Int::class) class MyClass
|
||||
|
||||
class Example(@field:Ann val foo, // annotate Java field
|
||||
@get:Ann val bar, // annotate Java getter
|
||||
@param:Ann val quux) // annotate Java constructor parameter
|
||||
class Example(@field:Ann val foo: String, // annotate Java field
|
||||
@get:Ann val bar: String, // annotate Java getter
|
||||
@param:Ann val quux: String) // annotate Java constructor parameter
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
@java.lang.annotation.Retention(null=java.lang.annotation.RetentionPolicy.RUNTIME)
|
||||
@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
|
||||
public abstract @interface SimpleAnn /* SimpleAnn*/ {
|
||||
@null()
|
||||
public abstract java.lang.String value();
|
||||
|
||||
}
|
||||
|
||||
@java.lang.annotation.Retention(null=java.lang.annotation.RetentionPolicy.RUNTIME)
|
||||
@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
|
||||
public abstract @interface Ann /* Ann*/ {
|
||||
@null()
|
||||
public abstract SimpleAnn[] t();
|
||||
@@ -27,16 +27,16 @@ public abstract @interface Ann /* Ann*/ {
|
||||
}
|
||||
|
||||
public abstract interface Base /* Base*/ {
|
||||
@Ann(null=1, null="134", null=String::class, null=arrayOf(Int::class, Double::class), null=DeprecationLevel.WARNING, null=SimpleAnn("243"), null=SimpleAnn("4324"))
|
||||
public abstract void foo(@Ann(null=2, null="324", null=Ann::class, null=arrayOf(Byte::class, Base::class), null=DeprecationLevel.WARNING, null=SimpleAnn("687"), null=SimpleAnn("78")) @org.jetbrains.annotations.NotNull() java.lang.String);
|
||||
@Ann(x = 1, y = "134", z = String::class, e = {Int::class, Double::class}, depr = DeprecationLevel.WARNING, t = {@SimpleAnn(value = "243"), @SimpleAnn(value = "4324")})
|
||||
public abstract void foo(@Ann(x = 2, y = "324", z = Ann::class, e = {Byte::class, Base::class}, depr = DeprecationLevel.WARNING, t = {@SimpleAnn(value = "687"), @SimpleAnn(value = "78")}) @org.jetbrains.annotations.NotNull() java.lang.String);
|
||||
|
||||
}
|
||||
|
||||
public final class Derived /* Derived*/ implements Base {
|
||||
@Ann(x=1, y="134", z=java.lang.String.class, e={int.class, double.class}, depr=kotlin.DeprecationLevel.WARNING, t={@SimpleAnn(value="243"), @SimpleAnn(value="4324")})
|
||||
public void foo(@Ann(x=2, y="324", z=Ann.class, e={byte.class, Base.class}, depr=kotlin.DeprecationLevel.WARNING, t={@SimpleAnn(value="687"), @SimpleAnn(value="78")}) @org.jetbrains.annotations.NotNull() java.lang.String);
|
||||
@Ann(x = 1, y = "134", z = java.lang.String.class, e = {int.class, double.class}, depr = kotlin.DeprecationLevel.WARNING, t = {@SimpleAnn(value="243"), @SimpleAnn(value="4324")})
|
||||
public void foo(@Ann(x = 2, y = "324", z = Ann.class, e = {byte.class, Base.class}, depr = kotlin.DeprecationLevel.WARNING, t = {@SimpleAnn(value="687"), @SimpleAnn(value="78")}) @org.jetbrains.annotations.NotNull() java.lang.String);
|
||||
|
||||
@null()
|
||||
public Derived(@org.jetbrains.annotations.NotNull() Base);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,13 @@
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
/** should load cls */
|
||||
annotation class SimpleAnn(val value: String)
|
||||
|
||||
/** should load cls */
|
||||
annotation class Ann(
|
||||
val x: Int,
|
||||
val y: String,
|
||||
val z: KClass<*>,
|
||||
val e: Array<KClass<*>>,
|
||||
val depr: DeprecationLevel
|
||||
val depr: DeprecationLevel,
|
||||
vararg val t: SimpleAnn
|
||||
)
|
||||
|
||||
|
||||
@@ -5,5 +5,4 @@ public class Testing {
|
||||
}
|
||||
|
||||
// EXIST: c
|
||||
// EXIST: d
|
||||
// LIGHT_CLASS: mockLib.foo.Anno
|
||||
// EXIST: d
|
||||
@@ -8,4 +8,3 @@ public class Testing {
|
||||
// EXIST: topLevelExtFunction
|
||||
// EXIST: getTopLevelVar
|
||||
// EXIST: setTopLevelVar
|
||||
// LIGHT_CLASS: mockLib.foo.MainKt
|
||||
|
||||
@@ -6,5 +6,4 @@ public class Testing {
|
||||
|
||||
// EXIST: topLevelFunction
|
||||
// EXIST: topLevelExtFunction
|
||||
// EXIST: getTopLevelVar, setTopLevelVar
|
||||
// LIGHT_CLASS: mockLib.foo.MainKt
|
||||
// EXIST: getTopLevelVar, setTopLevelVar
|
||||
@@ -467,6 +467,26 @@ class KtLightAnnotationTest : KotlinLightCodeInsightFixtureTestCase() {
|
||||
|
||||
}
|
||||
|
||||
fun testKtVarargAnnotation() {
|
||||
|
||||
myFixture.configureByText("Anno.kt", """
|
||||
annotation class Anno(vararg val vars: String)
|
||||
""")
|
||||
myFixture.configureByText("AnnotatedClass.kt", """
|
||||
@Anno("hello", "world")
|
||||
class MyAnnotated
|
||||
""".trimIndent())
|
||||
|
||||
val annotations = myFixture.findClass("MyAnnotated").expectAnnotations(1)
|
||||
val annotationAttributeVal = annotations.first().findAttributeValue("vars")
|
||||
annotationAttributeVal as PsiArrayInitializerMemberValue
|
||||
assertTextAndRange("(\"hello\", \"world\")", annotationAttributeVal)
|
||||
UsefulTestCase.assertInstanceOf(annotationAttributeVal.parent, PsiNameValuePair::class.java)
|
||||
UsefulTestCase.assertEquals(annotationAttributeVal.initializers.size, 2)
|
||||
assertTextAndRange("\"hello\"", annotationAttributeVal.initializers[0])
|
||||
assertTextAndRange("\"world\"", annotationAttributeVal.initializers[1])
|
||||
}
|
||||
|
||||
private fun doVarargTest(type: String, parameters: List<String>) {
|
||||
val paramsJoined = parameters.joinToString(", ")
|
||||
|
||||
@@ -574,7 +594,7 @@ class KtLightAnnotationTest : KotlinLightCodeInsightFixtureTestCase() {
|
||||
""".trimIndent())
|
||||
|
||||
myFixture.configureByText("AnnotatedClass.kt", """
|
||||
@Annotation(value = "a")
|
||||
@Annotation("a")
|
||||
open class AnnotatedClass
|
||||
""".trimIndent())
|
||||
myFixture.testHighlighting("Annotation.java", "AnnotatedClass.kt")
|
||||
|
||||
@@ -16,10 +16,12 @@ import junit.framework.TestCase
|
||||
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
|
||||
import org.jetbrains.kotlin.asJava.classes.*
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightNullabilityAnnotation
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightPsiArrayInitializerMemberValue
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.idea.project.languageVersionSettings
|
||||
import org.jetbrains.kotlin.load.kotlin.NON_EXISTENT_CLASS_NAME
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.psi.KtCallExpression
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.junit.Assert
|
||||
@@ -94,23 +96,40 @@ object UltraLightChecker {
|
||||
}
|
||||
}
|
||||
|
||||
private fun PsiAnnotation.renderAnnotation() =
|
||||
"@" + qualifiedName + "(" + parameterList.attributes.joinToString { it.name + "=" + (it.value?.text ?: "?") } + ")"
|
||||
private fun PsiAnnotation.renderAnnotation(): String {
|
||||
|
||||
val renderedAttributes = parameterList.attributes.map {
|
||||
val attributeValue = it.value?.renderAnnotationMemberValue() ?: "?"
|
||||
|
||||
val name = when {
|
||||
it.name === null && qualifiedName?.startsWith("java.lang.annotation.") == true -> "value"
|
||||
else -> it.name
|
||||
}
|
||||
|
||||
if (name !== null) "$name = $attributeValue" else attributeValue
|
||||
}
|
||||
return "@$qualifiedName(${renderedAttributes.joinToString()})"
|
||||
}
|
||||
|
||||
|
||||
private fun PsiModifierListOwner.renderModifiers(typeIfApplicable: PsiType? = null): String {
|
||||
val buffer = StringBuilder()
|
||||
val annotationsBuffer = mutableListOf<String>()
|
||||
for (annotation in annotations) {
|
||||
if (annotation is KtLightNullabilityAnnotation<*> && skipRenderingNullability(typeIfApplicable)) {
|
||||
continue
|
||||
}
|
||||
|
||||
buffer.append(annotation.renderAnnotation())
|
||||
buffer.append(if (this is PsiParameter) " " else "\n")
|
||||
annotationsBuffer.add(
|
||||
annotation.renderAnnotation() + (if (this is PsiParameter) " " else "\n")
|
||||
)
|
||||
}
|
||||
annotationsBuffer.sort()
|
||||
|
||||
val resultBuffer = StringBuffer(annotationsBuffer.joinToString(separator = ""))
|
||||
for (modifier in PsiModifier.MODIFIERS.filter(::hasModifierProperty)) {
|
||||
buffer.append(modifier).append(" ")
|
||||
resultBuffer.append(modifier).append(" ")
|
||||
}
|
||||
return buffer.toString()
|
||||
return resultBuffer.toString()
|
||||
}
|
||||
|
||||
private fun PsiModifierListOwner.skipRenderingNullability(typeIfApplicable: PsiType?) =
|
||||
@@ -127,9 +146,17 @@ object UltraLightChecker {
|
||||
|
||||
private fun PsiType.renderType() = getCanonicalText(true)
|
||||
|
||||
private fun PsiReferenceList?.renderRefList(keyword: String): String {
|
||||
if (this == null || this.referencedTypes.isEmpty()) return ""
|
||||
return " " + keyword + " " + referencedTypes.joinToString { it.renderType() }
|
||||
private fun PsiReferenceList?.renderRefList(keyword: String, sortReferences: Boolean = true): String {
|
||||
if (this == null) return ""
|
||||
|
||||
val references = referencedTypes
|
||||
if (references.isEmpty()) return ""
|
||||
|
||||
val referencesTypes = references.map { it.renderType() }.toTypedArray()
|
||||
|
||||
if (sortReferences) referencesTypes.sort()
|
||||
|
||||
return " " + keyword + " " + referencesTypes.joinToString()
|
||||
}
|
||||
|
||||
private fun PsiVariable.renderVar(): String {
|
||||
@@ -151,6 +178,12 @@ object UltraLightChecker {
|
||||
it.name!! + bounds
|
||||
} + "> "
|
||||
|
||||
private fun PsiAnnotationMemberValue.renderAnnotationMemberValue(): String = when (this) {
|
||||
is KtLightPsiArrayInitializerMemberValue -> "{${initializers.joinToString { it.renderAnnotationMemberValue() }}}"
|
||||
is PsiAnnotation -> renderAnnotation()
|
||||
else -> text
|
||||
}
|
||||
|
||||
private fun PsiMethod.renderMethod() =
|
||||
renderModifiers(returnType) +
|
||||
(if (isVarArgs) "/* vararg */ " else "") +
|
||||
@@ -158,7 +191,7 @@ object UltraLightChecker {
|
||||
(returnType?.renderType() ?: "") + " " +
|
||||
name +
|
||||
"(" + parameterList.parameters.joinToString { it.renderModifiers(it.type) + it.type.renderType() } + ")" +
|
||||
(this as? PsiAnnotationMethod)?.defaultValue?.let { " default " + it.text }.orEmpty() +
|
||||
(this as? PsiAnnotationMethod)?.defaultValue?.let { " default " + it.renderAnnotationMemberValue() }.orEmpty() +
|
||||
throwsList.referencedTypes.let { thrownTypes ->
|
||||
if (thrownTypes.isEmpty()) ""
|
||||
else " throws " + thrownTypes.joinToString { it.renderType() }
|
||||
|
||||
@@ -287,7 +287,7 @@ class CommonIntentionActionsTest : LightPlatformCodeInsightFixtureTestCase() {
|
||||
|
||||
TestCase.assertEquals(
|
||||
"KtUltraLightMethodForSourceDeclaration -> org.jetbrains.annotations.NotNull," +
|
||||
" KtUltraLightField -> pkg.myannotation.JavaAnnotation, org.jetbrains.annotations.NotNull",
|
||||
" KtUltraLightFieldForSourceDeclaration -> pkg.myannotation.JavaAnnotation, org.jetbrains.annotations.NotNull",
|
||||
annotationsString(myFixture.findElementByText("bar", KtModifierListOwner::class.java))
|
||||
)
|
||||
}
|
||||
@@ -339,7 +339,7 @@ class CommonIntentionActionsTest : LightPlatformCodeInsightFixtureTestCase() {
|
||||
|
||||
TestCase.assertEquals(
|
||||
"KtUltraLightMethodForSourceDeclaration -> org.jetbrains.annotations.NotNull," +
|
||||
" KtUltraLightField -> pkg.myannotation.JavaAnnotation, org.jetbrains.annotations.NotNull",
|
||||
" KtUltraLightFieldForSourceDeclaration -> pkg.myannotation.JavaAnnotation, org.jetbrains.annotations.NotNull",
|
||||
annotationsString(myFixture.findElementByText("bar", KtModifierListOwner::class.java))
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user