Skip to content

Commit 2bc6ad7

Browse files
committed
pass varargs literaly in kps's toAnnotaitonSpec()
This works around an issue where OptIn annotations fail to compile using the explicit array syntax Fixes #1831
1 parent 2e664a7 commit 2bc6ad7

File tree

3 files changed

+67
-4
lines changed

3 files changed

+67
-4
lines changed

interop/ksp/src/main/kotlin/com/squareup/kotlinpoet/ksp/Annotations.kt

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,19 +39,35 @@ public fun KSAnnotation.toAnnotationSpec(omitDefaultValues: Boolean = false): An
3939
is ParameterizedTypeName -> AnnotationSpec.builder(type)
4040
else -> error("This is never possible.")
4141
}
42+
val params = (annotationType.resolve().declaration as KSClassDeclaration).primaryConstructor?.parameters.orEmpty()
43+
.associateBy { it.name }
4244
useSiteTarget?.let { builder.useSiteTarget(it.kpAnalog) }
4345
// TODO support type params once they're exposed https://github.com/google/ksp/issues/753
46+
var varargValues: List<*>? = null
4447
for (argument in arguments) {
4548
val value = argument.value ?: continue
4649
val name = argument.name!!.getShortName()
50+
val type = params[argument.name]
4751
if (omitDefaultValues) {
4852
val defaultValue = this.defaultArguments.firstOrNull { it.name?.asString() == name }?.value
4953
if (isDefaultValue(value, defaultValue)) { continue }
5054
}
51-
val member = CodeBlock.builder()
52-
member.add("%N = ", name)
53-
addValueToBlock(value, member, omitDefaultValues)
54-
builder.addMember(member.build())
55+
if (type?.isVararg == true) {
56+
// wait to add varargs to end
57+
varargValues = value as List<*>
58+
} else {
59+
val member = CodeBlock.builder()
60+
member.add("%N = ", name)
61+
addValueToBlock(value, member, omitDefaultValues)
62+
builder.addMember(member.build())
63+
}
64+
if (varargValues != null) {
65+
for (item in varargValues) {
66+
val member = CodeBlock.builder()
67+
addValueToBlock(item!!, member, omitDefaultValues)
68+
builder.addMember(member.build())
69+
}
70+
}
5571
}
5672
return builder.build()
5773
}

interop/ksp/test-processor/src/main/kotlin/com/squareup/kotlinpoet/ksp/test/processor/exampleAnnotations.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,3 +79,5 @@ annotation class AnotherAnnotation(val input: String)
7979
enum class AnnotationEnumValue {
8080
ONE, TWO, THREE
8181
}
82+
83+
annotation class AnnotationWithVararg(vararg val args: String)

interop/ksp/test-processor/src/test/kotlin/com/squareup/kotlinpoet/ksp/test/processor/TestProcessorTest.kt

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -620,6 +620,51 @@ class TestProcessorTest {
620620
)
621621
}
622622

623+
@Test
624+
fun varargArgument() {
625+
val compilation = prepareCompilation(
626+
kotlin(
627+
"Example.kt",
628+
"""
629+
package test
630+
631+
import com.squareup.kotlinpoet.ksp.test.processor.AnnotationWithVararg
632+
import com.squareup.kotlinpoet.ksp.test.processor.ExampleAnnotation
633+
634+
@RequiresOptIn
635+
annotation class MyOptIn
636+
637+
@ExampleAnnotation
638+
@OptIn(MyOptIn::class)
639+
@AnnotationWithVararg("one", "two")
640+
interface Example
641+
""".trimIndent()
642+
)
643+
)
644+
645+
val result = compilation.compile()
646+
assertThat(result.exitCode).isEqualTo(KotlinCompilation.ExitCode.OK)
647+
val generatedFileText = File(compilation.kspSourcesDir, "kotlin/test/TestExample.kt")
648+
.readText()
649+
650+
assertThat(generatedFileText).isEqualTo(
651+
"""
652+
package test
653+
654+
import com.squareup.kotlinpoet.ksp.test.processor.AnnotationWithVararg
655+
import kotlin.OptIn
656+
657+
@OptIn(MyOptIn::class)
658+
@AnnotationWithVararg(
659+
"one",
660+
"two",
661+
)
662+
public class TestExample
663+
664+
""".trimIndent()
665+
)
666+
}
667+
623668
@Test
624669
fun regression_1513() {
625670
val compilation = prepareCompilation(

0 commit comments

Comments
 (0)