J2K: convert annotations properly

This commit is contained in:
Natalia Selezneva
2018-10-24 23:33:01 +03:00
parent ed1452c136
commit f364717da2
9 changed files with 43 additions and 28 deletions
@@ -190,7 +190,7 @@ class AnnotationConverter(private val converter: Converter) {
return converter.deferredElement { codeConverter ->
val convertedType = converter.typeConverter.convertType(returnType) as ArrayType
val convertAttributeValue = convertAttributeValue(value, returnType.componentType, false, false)
createArrayExpression(codeConverter, convertAttributeValue.toList(), convertedType, false)
createArrayLiteralExpression(codeConverter, convertAttributeValue.toList())
}
}
return converter.deferredElement(convertAttributeValue(value, returnType, false, false).single())
@@ -215,10 +215,21 @@ class AnnotationConverter(private val converter: Converter) {
}
is PsiAnnotation -> {
listOf({ _ ->
val (name, arguments) = convertAnnotationValue(value)!!
AnnotationConstructorCall(name, arguments).assignPrototype(value)
})
val annotationConstructor = listOf<(CodeConverter) -> Expression>(
{ _ ->
val (name, arguments) = convertAnnotationValue(value)!!
AnnotationConstructorCall(name, arguments).assignPrototype(value)
})
if (expectedType is PsiArrayType) {
listOf(
{ codeConverter ->
convertArrayInitializerValue(codeConverter, value.text, annotationConstructor, expectedType, isVararg)
.assignPrototype(value)
})
} else {
annotationConstructor
}
}
else -> listOf({ _ -> DummyStringExpression(value?.text ?: "").assignPrototype(value) })
}
@@ -253,20 +264,18 @@ class AnnotationConverter(private val converter: Converter) {
): Expression {
val expectedTypeConverted = converter.typeConverter.convertType(expectedType)
return if (expectedTypeConverted is ArrayType) {
createArrayExpression(codeConverter, componentGenerators, expectedTypeConverted, isVararg)
createArrayLiteralExpression(codeConverter, componentGenerators)
}
else {
DummyStringExpression(valueText)
}
}
private fun createArrayExpression(codeConverter: CodeConverter, componentGenerators: List<(CodeConverter) -> Expression>, expectedType: ArrayType, isVararg: Boolean): Expression {
val array = createArrayInitializerExpression(expectedType, componentGenerators.map { it(codeConverter) }, needExplicitType = false)
return if (isVararg) {
StarExpression(array.assignNoPrototype())
}
else {
array
}
private fun createArrayLiteralExpression(
codeConverter: CodeConverter,
componentGenerators: List<(CodeConverter) -> Expression>
): Expression {
val initializers = componentGenerators.map { it(codeConverter) }
return ArrayLiteralExpression(initializers)
}
}
@@ -98,6 +98,14 @@ open class LiteralExpression(val literalText: String) : Expression() {
}
}
class ArrayLiteralExpression(val expressions: List<Expression>) : Expression() {
override fun generateCode(builder: CodeBuilder) {
builder.append("[")
builder.append(expressions, ", ")
builder.append("]")
}
}
class ParenthesizedExpression(val expression: Expression) : Expression() {
override fun generateCode(builder: CodeBuilder) {
builder append "(" append expression append ")"
@@ -1,19 +1,19 @@
import kotlin.reflect.KClass
annotation class Ann(vararg val value: Inner, val test1: Array<InnerParam> = arrayOf(InnerParam(C::class)))
annotation class Ann(vararg val value: Inner, val test1: Array<InnerParam> = [InnerParam(C::class)])
annotation class Inner
annotation class InnerParam(val value: KClass<*>)
@Ann(value = *arrayOf(Inner(), Inner()), test1 = arrayOf(InnerParam(C::class)))
@Ann(value = [Inner(), Inner()], test1 = [InnerParam(C::class)])
class C
@Ann(Inner(), Inner())
class D
@Ann(value = Inner())
@Ann(value = [Inner()])
class E
@Ann(value = *arrayOf(Inner()), test1 = arrayOf(InnerParam(value = C::class)))
@Ann(value = [Inner()], test1 = [InnerParam(value = C::class)])
class F
@@ -1,6 +1,6 @@
import kotlin.reflect.KClass
annotation class Ann(val i: Int = 1, val i2: IntArray = intArrayOf(1), val i3: IntArray = intArrayOf(1), val klass: KClass<*> = A::class, val klass2: Array<KClass<*>> = arrayOf(A::class), val klass3: Array<KClass<*>> = arrayOf(A::class), val ann: Inner = Inner(), val ann2: Array<Inner> = arrayOf(Inner()), val ann3: Array<Inner> = arrayOf(Inner(), Inner()))
annotation class Ann(val i: Int = 1, val i2: IntArray = [1], val i3: IntArray = [1], val klass: KClass<*> = A::class, val klass2: Array<KClass<*>> = [A::class], val klass3: Array<KClass<*>> = [A::class], val ann: Inner = Inner(), val ann2: Array<Inner> = [Inner()], val ann3: Array<Inner> = [Inner(), Inner()])
class A
annotation class Inner
@@ -1,7 +1,7 @@
internal annotation class Anon(val stringArray: Array<String>, val intArray: IntArray, // string
val string: String)
@Anon(string = "a", stringArray = arrayOf("a", "b"), intArray = intArrayOf(1, 2))
@Anon(string = "a", stringArray = ["a", "b"], intArray = [1, 2])
@Target(AnnotationTarget.CONSTRUCTOR, AnnotationTarget.FIELD)
internal annotation class I
@@ -1,4 +1,4 @@
internal annotation class Anon(val s: String = "a", val stringArray: Array<String> = arrayOf("a", "b"), val intArray: IntArray)
internal annotation class Anon(val s: String = "a", val stringArray: Array<String> = ["a", "b"], val intArray: IntArray)
@Anon(intArray = intArrayOf(1, 2))
@Anon(intArray = [1, 2])
internal class A
@@ -1,5 +1,3 @@
// ERROR: Members are not allowed in annotation class
// ERROR: Members are not allowed in annotation class
internal annotation class Anon(val value: String) {
enum class E {
@@ -9,5 +9,5 @@ internal interface I2
@Anon("c", "d", x = 1)
internal interface I3
@Anon(value = *arrayOf("c", "d"))
@Anon(value = ["c", "d"])
internal interface I4
+3 -3
View File
@@ -3,14 +3,14 @@
// ERROR: This annotation is not applicable to target 'value parameter'
import javaApi.*
@Anon1(value = *arrayOf("a"), stringArray = arrayOf("b"), intArray = intArrayOf(1, 2), string = "x")
@Anon1(value = ["a"], stringArray = ["b"], intArray = [1, 2], string = "x")
@Anon2(value = "a", intValue = 1, charValue = 'a')
@Anon3(e = E.A, stringArray = arrayOf(), value = *arrayOf("a", "b"))
@Anon3(e = E.A, stringArray = [], value = ["a", "b"])
@Anon4("x", "y")
@Anon5(1)
@Anon6("x", "y")
@Anon7(String::class, StringBuilder::class)
@Anon8(classes = arrayOf(String::class, StringBuilder::class))
@Anon8(classes = [String::class, StringBuilder::class])
internal class C {
@Anon5(1)
@Deprecated("")