New J2K: Wrap single annotation parameter to arrayOf if array type is required

#KT-31726 fixed
This commit is contained in:
Ilya Kirillov
2019-05-31 16:59:31 +03:00
parent 7bc2fcd657
commit f660faed97
5 changed files with 54 additions and 12 deletions
@@ -5,8 +5,11 @@
package org.jetbrains.kotlin.nj2k.conversions
import com.intellij.psi.PsiClass
import com.intellij.psi.PsiMethod
import org.jetbrains.kotlin.load.java.structure.JavaArrayType
import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext
import org.jetbrains.kotlin.nj2k.isVarargsArgument
import org.jetbrains.kotlin.nj2k.primaryConstructor
import org.jetbrains.kotlin.nj2k.toExpression
import org.jetbrains.kotlin.nj2k.tree.*
import org.jetbrains.kotlin.nj2k.tree.impl.JKAnnotationNameParameterImpl
@@ -37,7 +40,7 @@ class AnnotationConversion(private val context: NewJ2kConverterContext) : Recurs
.detached()
.map { JKAnnotationParameterImpl(it) }
annotationParameter is JKAnnotationNameParameter
&& annotation.isVarargsArgument(index)
&& annotation.isVarargsArgument(annotationParameter.name.value)
&& annotation.classSymbol.target is JKClass
&& annotationParameter.value !is JKKtAnnotationArrayInitializerExpression -> {
listOf(
@@ -64,4 +67,34 @@ class AnnotationConversion(private val context: NewJ2kConverterContext) : Recurs
annotation.arguments = newParameters
}
private fun PsiMethod.isVarArgsAnnotationMethod(isNamedArgument: Boolean) =
isVarArgs || returnType is JavaArrayType || name == "value" && !isNamedArgument
private fun JKParameter.isVarArgsAnnotationParameter(isNamedArgument: Boolean) =
isVarArgs || type.type.isArrayType() || name.value == "value" && !isNamedArgument
private fun JKAnnotation.isVarargsArgument(index: Int) =
when (val target = classSymbol.target) {
is JKClass -> target.primaryConstructor()
?.parameters
?.getOrNull(index)
?.isVarArgsAnnotationParameter(isNamedArgument = false)
is PsiClass -> target.methods
.getOrNull(index)
?.isVarArgsAnnotationMethod(isNamedArgument = false)
else -> false
} ?: false
private fun JKAnnotation.isVarargsArgument(name: String): Boolean =
when (val target = classSymbol.target) {
is JKClass -> target.primaryConstructor()
?.parameters
?.firstOrNull { it.name.value == name }
?.isVarArgsAnnotationParameter(isNamedArgument = true)
is PsiClass -> target.methods
.firstOrNull { it.name == name }
?.isVarArgsAnnotationMethod(isNamedArgument = true)
else -> false
} ?: false
}
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.nj2k
import com.intellij.psi.PsiArrayType
import com.intellij.psi.PsiClass
import com.intellij.psi.tree.TokenSet
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
@@ -482,16 +483,6 @@ fun JKClass.primaryConstructor(): JKKtPrimaryConstructor? = classBody.declaratio
fun List<JKExpression>.toArgumentList(): JKArgumentList =
JKArgumentListImpl(map { JKArgumentImpl(it) })
fun JKAnnotation.isVarargsArgument(index: Int): Boolean {
val target = classSymbol.target
return when (target) {
is JKClass -> target.primaryConstructor()?.parameters?.getOrNull(index)?.isVarArgs
is PsiClass -> target.methods.getOrNull(index)?.let {
it.isVarArgs || it.name == "value"
}
else -> false
} ?: false
}
fun JKExpression.asStatement(): JKExpressionStatement =
+7
View File
@@ -0,0 +1,7 @@
//Annotation class:
public @interface Special {
String[] names(); //array is used
}
//Class with annotation:
@Special(names = "name1")
public class JClass {}
+6
View File
@@ -0,0 +1,6 @@
//Annotation class:
annotation class Special(val names: Array<String> //array is used
) //Class with annotation:
@Special(names = ["name1"])
class JClass
@@ -111,6 +111,11 @@ public class NewJavaToKotlinConverterSingleFileTestGenerated extends AbstractNew
runTest("nj2k/testData/newJ2k/annotations/jetbrainsNullable.java");
}
@TestMetadata("kt-31726.java")
public void testKt_31726() throws Exception {
runTest("nj2k/testData/newJ2k/annotations/kt-31726.java");
}
@TestMetadata("modifiersToAnnotationsFromPropertyAccessors.java")
public void testModifiersToAnnotationsFromPropertyAccessors() throws Exception {
runTest("nj2k/testData/newJ2k/annotations/modifiersToAnnotationsFromPropertyAccessors.java");