diff --git a/kotlin-analysis-api/src/test/kotlin/com/google/devtools/ksp/processor/AnnotationArrayValueTypeProcessor.kt b/kotlin-analysis-api/src/test/kotlin/com/google/devtools/ksp/processor/AnnotationArrayValueTypeProcessor.kt new file mode 100644 index 0000000000..43b7c19c26 --- /dev/null +++ b/kotlin-analysis-api/src/test/kotlin/com/google/devtools/ksp/processor/AnnotationArrayValueTypeProcessor.kt @@ -0,0 +1,56 @@ +/* + * Copyright 2026 Google LLC + * Copyright 2010-2026 JetBrains s.r.o. and Kotlin Programming Language contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.devtools.ksp.processor + +import com.google.devtools.ksp.getClassDeclarationByName +import com.google.devtools.ksp.processing.Resolver +import com.google.devtools.ksp.symbol.KSAnnotated + +class AnnotationArrayValueTypeProcessor : AbstractTestProcessor() { + private val results = mutableListOf() + + override fun process(resolver: Resolver): List { + logAnnotationArrayValues(resolver, "JavaAnnotated") + logAnnotationArrayValues(resolver, "KotlinAnnotated") + return emptyList() + } + + override fun toResult(): List { + return results + } + + private fun logAnnotationArrayValues(resolver: Resolver, className: String) { + val annotated = resolver.getClassDeclarationByName(className)!! + listOf("JavaAnnotation", "KotlinAnnotation").forEach { annotationName -> + val annotation = annotated.annotations.single { it.shortName.asString() == annotationName } + val argument = annotation.arguments.single() + val value = argument.value + val argumentName = argument.name?.asString() + results.add("$className $annotationName $argumentName is Array<*>: ${value is Array<*>}") + results.add("$className $annotationName $argumentName size: ${value.sizeOrNull()}") + } + } + + private fun Any?.sizeOrNull(): Int? { + return when (this) { + is Array<*> -> size + is Collection<*> -> size + else -> null + } + } +} diff --git a/kotlin-analysis-api/src/test/kotlin/com/google/devtools/ksp/test/AAConfiguredUnitTestSuite.kt b/kotlin-analysis-api/src/test/kotlin/com/google/devtools/ksp/test/AAConfiguredUnitTestSuite.kt index 402889a526..b471136b07 100644 --- a/kotlin-analysis-api/src/test/kotlin/com/google/devtools/ksp/test/AAConfiguredUnitTestSuite.kt +++ b/kotlin-analysis-api/src/test/kotlin/com/google/devtools/ksp/test/AAConfiguredUnitTestSuite.kt @@ -28,6 +28,12 @@ class AAConfiguredUnitTestSuite : KSPUnitTestSuite(experimentalPsiResolution = f runTest("$AA_PATH/getSymbolsWithAnnotation/aliasedAnnotation.kt") } + @TestMetadata("annotationArrayValueType.kt") + @Test + override fun testAnnotationArrayValueType() { + runFailingTest("$AA_PATH/annotationArrayValueType.kt") + } + @TestMetadata("allUseSiteTargetAppliedToAnnotationList.kt") @Test override fun testAllUseSiteTargetAppliedToAnnotationList() { diff --git a/kotlin-analysis-api/src/test/kotlin/com/google/devtools/ksp/test/KSPUnitTestSuite.kt b/kotlin-analysis-api/src/test/kotlin/com/google/devtools/ksp/test/KSPUnitTestSuite.kt index e4ac7ae95f..2534b42c26 100644 --- a/kotlin-analysis-api/src/test/kotlin/com/google/devtools/ksp/test/KSPUnitTestSuite.kt +++ b/kotlin-analysis-api/src/test/kotlin/com/google/devtools/ksp/test/KSPUnitTestSuite.kt @@ -152,6 +152,9 @@ abstract class KSPUnitTestSuite( runTest("$AA_PATH/annotationWithArrayValue.kt") } + @Bug("https://github.com/google/ksp/issues/3008", BugState.OPEN) + abstract fun testAnnotationArrayValueType() + @TestMetadata("annotationWithDefault.kt") @Test fun testAnnotationWithDefault() { diff --git a/kotlin-analysis-api/src/test/kotlin/com/google/devtools/ksp/test/PsiConfiguredUnitTestSuite.kt b/kotlin-analysis-api/src/test/kotlin/com/google/devtools/ksp/test/PsiConfiguredUnitTestSuite.kt index 6b9d875dd9..2be0ea332e 100644 --- a/kotlin-analysis-api/src/test/kotlin/com/google/devtools/ksp/test/PsiConfiguredUnitTestSuite.kt +++ b/kotlin-analysis-api/src/test/kotlin/com/google/devtools/ksp/test/PsiConfiguredUnitTestSuite.kt @@ -28,6 +28,12 @@ class PsiConfiguredUnitTestSuite : KSPUnitTestSuite(experimentalPsiResolution = runFailingTest("$AA_PATH/getSymbolsWithAnnotation/aliasedAnnotation.kt") } + @TestMetadata("annotationArrayValueType.kt") + @Test + override fun testAnnotationArrayValueType() { + runFailingTest("$AA_PATH/annotationArrayValueType.kt") + } + @TestMetadata("allUseSiteTargetAppliedToAnnotationList.kt") @Test override fun testAllUseSiteTargetAppliedToAnnotationList() { diff --git a/kotlin-analysis-api/testData/annotationArrayValueType.kt b/kotlin-analysis-api/testData/annotationArrayValueType.kt new file mode 100644 index 0000000000..aa87c52a37 --- /dev/null +++ b/kotlin-analysis-api/testData/annotationArrayValueType.kt @@ -0,0 +1,50 @@ +/* + * Copyright 2026 Google LLC + * Copyright 2010-2026 JetBrains s.r.o. and Kotlin Programming Language contributors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// TEST PROCESSOR: AnnotationArrayValueTypeProcessor +// EXPECTED: +// JavaAnnotated JavaAnnotation args is Array<*>: true +// JavaAnnotated JavaAnnotation args size: 2 +// JavaAnnotated KotlinAnnotation args is Array<*>: true +// JavaAnnotated KotlinAnnotation args size: 2 +// KotlinAnnotated JavaAnnotation args is Array<*>: true +// KotlinAnnotated JavaAnnotation args size: 2 +// KotlinAnnotated KotlinAnnotation args is Array<*>: true +// KotlinAnnotated KotlinAnnotation args size: 2 +// END +// FILE: JavaAnnotation.java +public @interface JavaAnnotation { + NestedAnnotation[] args(); +} + +// FILE: NestedAnnotation.java +public @interface NestedAnnotation { + String value(); +} + +// FILE: JavaAnnotated.java +@JavaAnnotation(args = {@NestedAnnotation(value = "one"), @NestedAnnotation(value = "two")}) +@KotlinAnnotation(args = {@KotlinNestedAnnotation(value = "one"), @KotlinNestedAnnotation(value = "two")}) +class JavaAnnotated {} + +// FILE: KotlinAnnotated.kt +annotation class KotlinAnnotation(val args: Array) + +annotation class KotlinNestedAnnotation(val value: String) + +@JavaAnnotation(args = [NestedAnnotation(value = "one"), NestedAnnotation(value = "two")]) +@KotlinAnnotation(args = [KotlinNestedAnnotation(value = "one"), KotlinNestedAnnotation(value = "two")]) +class KotlinAnnotated