Fix UL-classes test renders and test data

This commit is contained in:
Igor Yakovlev
2019-07-01 18:07:12 +03:00
parent 4b1226e3d7
commit a9aa60491e
9 changed files with 105 additions and 38 deletions
+28 -9
View File
@@ -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
+1 -2
View File
@@ -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))
)
}