From f660faed97a4d8e62349c4a529aace8189c35297 Mon Sep 17 00:00:00 2001 From: Ilya Kirillov Date: Fri, 31 May 2019 16:59:31 +0300 Subject: [PATCH] New J2K: Wrap single annotation parameter to arrayOf if array type is required #KT-31726 fixed --- .../nj2k/conversions/AnnotationConversion.kt | 37 ++++++++++++++++++- .../org/jetbrains/kotlin/nj2k/expressions.kt | 11 +----- .../testData/newJ2k/annotations/kt-31726.java | 7 ++++ nj2k/testData/newJ2k/annotations/kt-31726.kt | 6 +++ ...otlinConverterSingleFileTestGenerated.java | 5 +++ 5 files changed, 54 insertions(+), 12 deletions(-) create mode 100644 nj2k/testData/newJ2k/annotations/kt-31726.java create mode 100644 nj2k/testData/newJ2k/annotations/kt-31726.kt diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/AnnotationConversion.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/AnnotationConversion.kt index 6faa4d80e35..b0c5d179584 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/AnnotationConversion.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/AnnotationConversion.kt @@ -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 } \ No newline at end of file diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/expressions.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/expressions.kt index 9ebcb92a6f1..7fbad281cea 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/expressions.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/expressions.kt @@ -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.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 = diff --git a/nj2k/testData/newJ2k/annotations/kt-31726.java b/nj2k/testData/newJ2k/annotations/kt-31726.java new file mode 100644 index 00000000000..c6933b27650 --- /dev/null +++ b/nj2k/testData/newJ2k/annotations/kt-31726.java @@ -0,0 +1,7 @@ +//Annotation class: +public @interface Special { + String[] names(); //array is used +} +//Class with annotation: +@Special(names = "name1") +public class JClass {} \ No newline at end of file diff --git a/nj2k/testData/newJ2k/annotations/kt-31726.kt b/nj2k/testData/newJ2k/annotations/kt-31726.kt new file mode 100644 index 00000000000..c307be66e3c --- /dev/null +++ b/nj2k/testData/newJ2k/annotations/kt-31726.kt @@ -0,0 +1,6 @@ +//Annotation class: +annotation class Special(val names: Array //array is used +) //Class with annotation: + +@Special(names = ["name1"]) +class JClass \ No newline at end of file diff --git a/nj2k/tests/org/jetbrains/kotlin/nj2k/NewJavaToKotlinConverterSingleFileTestGenerated.java b/nj2k/tests/org/jetbrains/kotlin/nj2k/NewJavaToKotlinConverterSingleFileTestGenerated.java index 601fc22ff58..1e635114cc1 100644 --- a/nj2k/tests/org/jetbrains/kotlin/nj2k/NewJavaToKotlinConverterSingleFileTestGenerated.java +++ b/nj2k/tests/org/jetbrains/kotlin/nj2k/NewJavaToKotlinConverterSingleFileTestGenerated.java @@ -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");