Fix UL-classes test renders and test data
This commit is contained in:
+28
-9
@@ -1,9 +1,29 @@
|
|||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
/** should load cls */
|
@Target(*[AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.EXPRESSION])
|
||||||
annotation class Anno(val p: String = "", val x: Array<Anno> = arrayOf(Anno(p="a"), Anno(p="b")))
|
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,
|
@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION,
|
||||||
AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.EXPRESSION)
|
AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.EXPRESSION)
|
||||||
@Retention(AnnotationRetention.SOURCE)
|
@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"))
|
@Deprecated("This anno is deprecated, use === instead", ReplaceWith("this === other"))
|
||||||
annotation class Fancy
|
annotation class Fancy
|
||||||
|
|
||||||
/** should load cls */
|
|
||||||
annotation class ReplaceWith(val expression: String)
|
annotation class ReplaceWith(val expression: String)
|
||||||
|
|
||||||
/** should load cls */
|
annotation class AnnotatedAttribute(@get:Anno val x: String)
|
||||||
|
|
||||||
annotation class Deprecated(
|
annotation class Deprecated(
|
||||||
val message: String,
|
val message: String,
|
||||||
val replaceWith: ReplaceWith = ReplaceWith(""))
|
val replaceWith: ReplaceWith = ReplaceWith(""))
|
||||||
|
|
||||||
/** should load cls */
|
|
||||||
annotation class Ann(val arg1: KClass<*>, val arg2: KClass<out Any>)
|
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
|
@Ann(String::class, Int::class) class MyClass
|
||||||
|
|
||||||
class Example(@field:Ann val foo, // annotate Java field
|
class Example(@field:Ann val foo: String, // annotate Java field
|
||||||
@get:Ann val bar, // annotate Java getter
|
@get:Ann val bar: String, // annotate Java getter
|
||||||
@param:Ann val quux) // annotate Java constructor parameter
|
@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*/ {
|
public abstract @interface SimpleAnn /* SimpleAnn*/ {
|
||||||
@null()
|
@null()
|
||||||
public abstract java.lang.String value();
|
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*/ {
|
public abstract @interface Ann /* Ann*/ {
|
||||||
@null()
|
@null()
|
||||||
public abstract SimpleAnn[] t();
|
public abstract SimpleAnn[] t();
|
||||||
@@ -27,14 +27,14 @@ public abstract @interface Ann /* Ann*/ {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public abstract interface Base /* Base*/ {
|
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"))
|
@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(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);
|
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 {
|
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")})
|
@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);
|
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()
|
@null()
|
||||||
public Derived(@org.jetbrains.annotations.NotNull() Base);
|
public Derived(@org.jetbrains.annotations.NotNull() Base);
|
||||||
|
|||||||
@@ -1,15 +1,13 @@
|
|||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
/** should load cls */
|
|
||||||
annotation class SimpleAnn(val value: String)
|
annotation class SimpleAnn(val value: String)
|
||||||
|
|
||||||
/** should load cls */
|
|
||||||
annotation class Ann(
|
annotation class Ann(
|
||||||
val x: Int,
|
val x: Int,
|
||||||
val y: String,
|
val y: String,
|
||||||
val z: KClass<*>,
|
val z: KClass<*>,
|
||||||
val e: Array<KClass<*>>,
|
val e: Array<KClass<*>>,
|
||||||
val depr: DeprecationLevel
|
val depr: DeprecationLevel,
|
||||||
vararg val t: SimpleAnn
|
vararg val t: SimpleAnn
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -6,4 +6,3 @@ public class Testing {
|
|||||||
|
|
||||||
// EXIST: c
|
// EXIST: c
|
||||||
// EXIST: d
|
// EXIST: d
|
||||||
// LIGHT_CLASS: mockLib.foo.Anno
|
|
||||||
@@ -8,4 +8,3 @@ public class Testing {
|
|||||||
// EXIST: topLevelExtFunction
|
// EXIST: topLevelExtFunction
|
||||||
// EXIST: getTopLevelVar
|
// EXIST: getTopLevelVar
|
||||||
// EXIST: setTopLevelVar
|
// EXIST: setTopLevelVar
|
||||||
// LIGHT_CLASS: mockLib.foo.MainKt
|
|
||||||
|
|||||||
@@ -7,4 +7,3 @@ public class Testing {
|
|||||||
// EXIST: topLevelFunction
|
// EXIST: topLevelFunction
|
||||||
// EXIST: topLevelExtFunction
|
// EXIST: topLevelExtFunction
|
||||||
// EXIST: getTopLevelVar, setTopLevelVar
|
// EXIST: getTopLevelVar, setTopLevelVar
|
||||||
// LIGHT_CLASS: mockLib.foo.MainKt
|
|
||||||
@@ -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>) {
|
private fun doVarargTest(type: String, parameters: List<String>) {
|
||||||
val paramsJoined = parameters.joinToString(", ")
|
val paramsJoined = parameters.joinToString(", ")
|
||||||
|
|
||||||
@@ -574,7 +594,7 @@ class KtLightAnnotationTest : KotlinLightCodeInsightFixtureTestCase() {
|
|||||||
""".trimIndent())
|
""".trimIndent())
|
||||||
|
|
||||||
myFixture.configureByText("AnnotatedClass.kt", """
|
myFixture.configureByText("AnnotatedClass.kt", """
|
||||||
@Annotation(value = "a")
|
@Annotation("a")
|
||||||
open class AnnotatedClass
|
open class AnnotatedClass
|
||||||
""".trimIndent())
|
""".trimIndent())
|
||||||
myFixture.testHighlighting("Annotation.java", "AnnotatedClass.kt")
|
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.LightClassGenerationSupport
|
||||||
import org.jetbrains.kotlin.asJava.classes.*
|
import org.jetbrains.kotlin.asJava.classes.*
|
||||||
import org.jetbrains.kotlin.asJava.elements.KtLightNullabilityAnnotation
|
import org.jetbrains.kotlin.asJava.elements.KtLightNullabilityAnnotation
|
||||||
|
import org.jetbrains.kotlin.asJava.elements.KtLightPsiArrayInitializerMemberValue
|
||||||
import org.jetbrains.kotlin.config.LanguageFeature
|
import org.jetbrains.kotlin.config.LanguageFeature
|
||||||
import org.jetbrains.kotlin.idea.project.languageVersionSettings
|
import org.jetbrains.kotlin.idea.project.languageVersionSettings
|
||||||
import org.jetbrains.kotlin.load.kotlin.NON_EXISTENT_CLASS_NAME
|
import org.jetbrains.kotlin.load.kotlin.NON_EXISTENT_CLASS_NAME
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
import org.jetbrains.kotlin.psi.KtCallExpression
|
||||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.junit.Assert
|
import org.junit.Assert
|
||||||
@@ -94,23 +96,40 @@ object UltraLightChecker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun PsiAnnotation.renderAnnotation() =
|
private fun PsiAnnotation.renderAnnotation(): String {
|
||||||
"@" + qualifiedName + "(" + parameterList.attributes.joinToString { it.name + "=" + (it.value?.text ?: "?") } + ")"
|
|
||||||
|
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 {
|
private fun PsiModifierListOwner.renderModifiers(typeIfApplicable: PsiType? = null): String {
|
||||||
val buffer = StringBuilder()
|
val annotationsBuffer = mutableListOf<String>()
|
||||||
for (annotation in annotations) {
|
for (annotation in annotations) {
|
||||||
if (annotation is KtLightNullabilityAnnotation<*> && skipRenderingNullability(typeIfApplicable)) {
|
if (annotation is KtLightNullabilityAnnotation<*> && skipRenderingNullability(typeIfApplicable)) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer.append(annotation.renderAnnotation())
|
annotationsBuffer.add(
|
||||||
buffer.append(if (this is PsiParameter) " " else "\n")
|
annotation.renderAnnotation() + (if (this is PsiParameter) " " else "\n")
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
annotationsBuffer.sort()
|
||||||
|
|
||||||
|
val resultBuffer = StringBuffer(annotationsBuffer.joinToString(separator = ""))
|
||||||
for (modifier in PsiModifier.MODIFIERS.filter(::hasModifierProperty)) {
|
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?) =
|
private fun PsiModifierListOwner.skipRenderingNullability(typeIfApplicable: PsiType?) =
|
||||||
@@ -127,9 +146,17 @@ object UltraLightChecker {
|
|||||||
|
|
||||||
private fun PsiType.renderType() = getCanonicalText(true)
|
private fun PsiType.renderType() = getCanonicalText(true)
|
||||||
|
|
||||||
private fun PsiReferenceList?.renderRefList(keyword: String): String {
|
private fun PsiReferenceList?.renderRefList(keyword: String, sortReferences: Boolean = true): String {
|
||||||
if (this == null || this.referencedTypes.isEmpty()) return ""
|
if (this == null) return ""
|
||||||
return " " + keyword + " " + referencedTypes.joinToString { it.renderType() }
|
|
||||||
|
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 {
|
private fun PsiVariable.renderVar(): String {
|
||||||
@@ -151,6 +178,12 @@ object UltraLightChecker {
|
|||||||
it.name!! + bounds
|
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() =
|
private fun PsiMethod.renderMethod() =
|
||||||
renderModifiers(returnType) +
|
renderModifiers(returnType) +
|
||||||
(if (isVarArgs) "/* vararg */ " else "") +
|
(if (isVarArgs) "/* vararg */ " else "") +
|
||||||
@@ -158,7 +191,7 @@ object UltraLightChecker {
|
|||||||
(returnType?.renderType() ?: "") + " " +
|
(returnType?.renderType() ?: "") + " " +
|
||||||
name +
|
name +
|
||||||
"(" + parameterList.parameters.joinToString { it.renderModifiers(it.type) + it.type.renderType() } + ")" +
|
"(" + 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 ->
|
throwsList.referencedTypes.let { thrownTypes ->
|
||||||
if (thrownTypes.isEmpty()) ""
|
if (thrownTypes.isEmpty()) ""
|
||||||
else " throws " + thrownTypes.joinToString { it.renderType() }
|
else " throws " + thrownTypes.joinToString { it.renderType() }
|
||||||
|
|||||||
@@ -287,7 +287,7 @@ class CommonIntentionActionsTest : LightPlatformCodeInsightFixtureTestCase() {
|
|||||||
|
|
||||||
TestCase.assertEquals(
|
TestCase.assertEquals(
|
||||||
"KtUltraLightMethodForSourceDeclaration -> org.jetbrains.annotations.NotNull," +
|
"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))
|
annotationsString(myFixture.findElementByText("bar", KtModifierListOwner::class.java))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -339,7 +339,7 @@ class CommonIntentionActionsTest : LightPlatformCodeInsightFixtureTestCase() {
|
|||||||
|
|
||||||
TestCase.assertEquals(
|
TestCase.assertEquals(
|
||||||
"KtUltraLightMethodForSourceDeclaration -> org.jetbrains.annotations.NotNull," +
|
"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))
|
annotationsString(myFixture.findElementByText("bar", KtModifierListOwner::class.java))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user