diff options
11 files changed, 230 insertions, 60 deletions
diff --git a/compiler-plugin/src/test/kotlin/com/google/devtools/ksp/test/KSPCompilerPluginTest.kt b/compiler-plugin/src/test/kotlin/com/google/devtools/ksp/test/KSPCompilerPluginTest.kt index 4c23c905..58ebfee6 100644 --- a/compiler-plugin/src/test/kotlin/com/google/devtools/ksp/test/KSPCompilerPluginTest.kt +++ b/compiler-plugin/src/test/kotlin/com/google/devtools/ksp/test/KSPCompilerPluginTest.kt @@ -80,10 +80,16 @@ class KSPCompilerPluginTest : AbstractKSPCompilerPluginTest() { runTest("testData/api/annotationWithArbitraryClassValue.kt") } - @TestMetadata("annotationValue.kt") + @TestMetadata("annotationValue_java.kt") @Test - fun testAnnotationValue() { - runTest("testData/api/annotationValue.kt") + fun testAnnotationValue_java() { + runTest("../compiler-plugin/testData/api/annotationValue_java.kt") + } + + @TestMetadata("annotationValue_kt.kt") + @Test + fun testAnnotationValue_kt() { + runTest("testData/api/annotationValue_kt.kt") } @TestMetadata("annotationWithArrayValue.kt") diff --git a/compiler-plugin/testData/api/annotationValue.kt b/compiler-plugin/testData/api/annotationValue_java.kt index 700c951e..448ea5e0 100644 --- a/compiler-plugin/testData/api/annotationValue.kt +++ b/compiler-plugin/testData/api/annotationValue_java.kt @@ -22,17 +22,6 @@ // 42 // Foo // File -// Local -// Array -// @Foo -// @Suppress -// G -// ONE -// 31 -// Str -// 42 -// Foo -// File // Error type synthetic declaration // Array // @Foo @@ -41,7 +30,6 @@ // ONE // 31 // [warning1, warning 2] -// Throws // END // FILE: a.kt @@ -49,12 +37,6 @@ enum class RGB { R, G, B } -class ThrowsClass { - @Throws(Exception::class) - protected open fun throwsException() { - } -} - annotation class Foo(val s: Int) annotation class Bar( @@ -71,11 +53,6 @@ annotation class Bar( val argDef: Int = 31 ) -fun Fun() { - @Bar("Str", 40 + 2, Foo::class, java.io.File::class, Local::class, Array<String>::class, Foo(17), Suppress("name1", "name2"), RGB.G, JavaEnum.ONE) - class Local -} - // FILE: C.java @SuppressWarnings({"warning1", "warning 2"}) diff --git a/compiler-plugin/testData/api/annotationValue_kt.kt b/compiler-plugin/testData/api/annotationValue_kt.kt new file mode 100644 index 00000000..28c28772 --- /dev/null +++ b/compiler-plugin/testData/api/annotationValue_kt.kt @@ -0,0 +1,73 @@ +/* + * Copyright 2020 Google LLC + * Copyright 2010-2020 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. + */ + +// WITH_RUNTIME +// TEST PROCESSOR: AnnotationArgumentProcessor +// EXPECTED: +// defaultInNested +// Str +// 42 +// Foo +// File +// Local +// Array +// @Foo +// @Suppress +// G +// ONE +// 31 +// Throws +// END +// FILE: a.kt + +enum class RGB { + R, G, B +} + +class ThrowsClass { + @Throws(Exception::class) + protected open fun throwsException() { + } +} + +annotation class Foo(val s: Int) { + annotation class Nested(val nestedDefault:String = "defaultInNested") +} + +annotation class Bar( + val argStr: String, + val argInt: Int, + val argClsUser: kotlin.reflect.KClass<*>, + val argClsLib: kotlin.reflect.KClass<*>, + val argClsLocal: kotlin.reflect.KClass<*>, + val argClsArray: kotlin.reflect.KClass<*>, + val argAnnoUser: Foo, + val argAnnoLib: Suppress, + val argEnum: RGB, + val argJavaNum: JavaEnum, + val argDef: Int = 31 +) + +fun Fun() { + @Foo.Nested + @Bar("Str", 40 + 2, Foo::class, java.io.File::class, Local::class, Array<String>::class, Foo(17), Suppress("name1", "name2"), RGB.G, JavaEnum.ONE) + class Local +} + +// FILE: JavaEnum.java + +enum JavaEnum { ONE, TWO, THREE } diff --git a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSAnnotationImpl.kt b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSAnnotationImpl.kt index 377523e9..f8cbe68b 100644 --- a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSAnnotationImpl.kt +++ b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSAnnotationImpl.kt @@ -20,8 +20,14 @@ package com.google.devtools.ksp.impl.symbol.kotlin import com.google.devtools.ksp.KSObjectCache import com.google.devtools.ksp.symbol.* import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationApplication +import org.jetbrains.kotlin.analysis.api.annotations.KtConstantAnnotationValue +import org.jetbrains.kotlin.analysis.api.annotations.KtNamedAnnotationValue +import org.jetbrains.kotlin.analysis.api.base.KtConstantValue +import org.jetbrains.kotlin.analysis.api.components.KtConstantEvaluationMode import org.jetbrains.kotlin.analysis.api.components.buildClassType +import org.jetbrains.kotlin.analysis.api.symbols.KtValueParameterSymbol import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget.* +import org.jetbrains.kotlin.psi.KtParameter class KSAnnotationImpl private constructor(private val annotationApplication: KtAnnotationApplication) : KSAnnotation { companion object : KSObjectCache<KtAnnotationApplication, KSAnnotationImpl>() { @@ -36,7 +42,26 @@ class KSAnnotationImpl private constructor(private val annotationApplication: Kt } override val arguments: List<KSValueArgument> by lazy { - annotationApplication.arguments.map { KSValueArgumentImpl.getCached(it) } + val presentArgs = annotationApplication.arguments.map { KSValueArgumentImpl.getCached(it) } + val presentNames = presentArgs.mapNotNull { it.name?.asString() } + val absentArgs = analyze { + annotationApplication.classId?.getCorrespondingToplevelClassOrObjectSymbol()?.let { symbol -> + symbol.getMemberScope().getConstructors().singleOrNull()?.let { constructor -> + constructor.valueParameters.filter { valueParameter -> + valueParameter.name.asString() !in presentNames + }.mapNotNull { valueParameterSymbol -> + valueParameterSymbol.getDefaultValue()?.let { constantValue -> + KSValueArgumentImpl.getCached( + KtNamedAnnotationValue( + valueParameterSymbol.name, KtConstantAnnotationValue(constantValue) + ) + ) + } + } + } + } ?: emptyList<KSValueArgument>() + } + presentArgs + absentArgs } override val defaultArguments: List<KSValueArgument> @@ -78,3 +103,14 @@ class KSAnnotationImpl private constructor(private val annotationApplication: Kt return "@${shortName.asString()}" } } + +internal fun KtValueParameterSymbol.getDefaultValue(): KtConstantValue? { + return this.psi?.let { + when (it) { + is KtParameter -> analyze { + it.defaultValue?.evaluate(KtConstantEvaluationMode.CONSTANT_EXPRESSION_EVALUATION) + } + else -> throw IllegalStateException("Unhandled default value type ${it.javaClass}") + } + } +} diff --git a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSClassDeclarationImpl.kt b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSClassDeclarationImpl.kt index 71cbdf4a..bd9ff0b8 100644 --- a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSClassDeclarationImpl.kt +++ b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSClassDeclarationImpl.kt @@ -23,21 +23,21 @@ import org.jetbrains.kotlin.analysis.api.components.buildClassType import org.jetbrains.kotlin.analysis.api.symbols.* import org.jetbrains.kotlin.psi.KtObjectDeclaration -class KSClassDeclarationImpl private constructor(private val ktNamedClassOrObjectSymbol: KtNamedClassOrObjectSymbol) : +class KSClassDeclarationImpl private constructor(private val ktClassOrObjectSymbol: KtClassOrObjectSymbol) : KSClassDeclaration, - AbstractKSDeclarationImpl(ktNamedClassOrObjectSymbol), - KSExpectActual by KSExpectActualImpl(ktNamedClassOrObjectSymbol) { - companion object : KSObjectCache<KtNamedClassOrObjectSymbol, KSClassDeclarationImpl>() { - fun getCached(ktNamedClassOrObjectSymbol: KtNamedClassOrObjectSymbol) = - cache.getOrPut(ktNamedClassOrObjectSymbol) { KSClassDeclarationImpl(ktNamedClassOrObjectSymbol) } + AbstractKSDeclarationImpl(ktClassOrObjectSymbol), + KSExpectActual by KSExpectActualImpl(ktClassOrObjectSymbol) { + companion object : KSObjectCache<KtClassOrObjectSymbol, KSClassDeclarationImpl>() { + fun getCached(ktClassOrObjectSymbol: KtClassOrObjectSymbol) = + cache.getOrPut(ktClassOrObjectSymbol) { KSClassDeclarationImpl(ktClassOrObjectSymbol) } } override val qualifiedName: KSName? by lazy { - ktNamedClassOrObjectSymbol.classIdIfNonLocal?.asFqNameString()?.let { KSNameImpl.getCached(it) } + ktClassOrObjectSymbol.classIdIfNonLocal?.asFqNameString()?.let { KSNameImpl.getCached(it) } } override val classKind: ClassKind by lazy { - when (ktNamedClassOrObjectSymbol.classKind) { + when (ktClassOrObjectSymbol.classKind) { KtClassKind.CLASS -> ClassKind.CLASS KtClassKind.ENUM_CLASS -> ClassKind.ENUM_CLASS KtClassKind.ANNOTATION_CLASS -> ClassKind.ANNOTATION_CLASS @@ -48,7 +48,7 @@ class KSClassDeclarationImpl private constructor(private val ktNamedClassOrObjec override val primaryConstructor: KSFunctionDeclaration? by lazy { analyze { - ktNamedClassOrObjectSymbol.getMemberScope().getConstructors().singleOrNull { it.isPrimary }?.let { + ktClassOrObjectSymbol.getMemberScope().getConstructors().singleOrNull { it.isPrimary }?.let { KSFunctionDeclarationImpl.getCached(it) } } @@ -56,12 +56,12 @@ class KSClassDeclarationImpl private constructor(private val ktNamedClassOrObjec override val superTypes: Sequence<KSTypeReference> by lazy { analyze { - ktNamedClassOrObjectSymbol.superTypes.map { KSTypeReferenceImpl(it) }.asSequence() + ktClassOrObjectSymbol.superTypes.map { KSTypeReferenceImpl(it) }.asSequence() } } override val isCompanionObject: Boolean by lazy { - (ktNamedClassOrObjectSymbol.psi as? KtObjectDeclaration)?.isCompanion() ?: false + (ktClassOrObjectSymbol.psi as? KtObjectDeclaration)?.isCompanion() ?: false } override fun getSealedSubclasses(): Sequence<KSClassDeclaration> { @@ -69,11 +69,11 @@ class KSClassDeclarationImpl private constructor(private val ktNamedClassOrObjec } override fun getAllFunctions(): Sequence<KSFunctionDeclaration> { - return ktNamedClassOrObjectSymbol.getAllFunctions() + return ktClassOrObjectSymbol.getAllFunctions() } override fun getAllProperties(): Sequence<KSPropertyDeclaration> { - return ktNamedClassOrObjectSymbol.getAllProperties() + return ktClassOrObjectSymbol.getAllProperties() } override fun asType(typeArguments: List<KSTypeArgument>): KSType { @@ -82,7 +82,7 @@ class KSClassDeclarationImpl private constructor(private val ktNamedClassOrObjec override fun asStarProjectedType(): KSType { return analyze { - KSTypeImpl.getCached(analysisSession.buildClassType(ktNamedClassOrObjectSymbol)) + KSTypeImpl.getCached(analysisSession.buildClassType(ktClassOrObjectSymbol)) } } @@ -91,6 +91,6 @@ class KSClassDeclarationImpl private constructor(private val ktNamedClassOrObjec } override val declarations: Sequence<KSDeclaration> by lazy { - ktNamedClassOrObjectSymbol.declarations() + ktClassOrObjectSymbol.declarations() } } diff --git a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSFunctionDeclarationImpl.kt b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSFunctionDeclarationImpl.kt index 807d098a..8bbade9d 100644 --- a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSFunctionDeclarationImpl.kt +++ b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSFunctionDeclarationImpl.kt @@ -22,6 +22,8 @@ import com.google.devtools.ksp.symbol.* import org.jetbrains.kotlin.analysis.api.symbols.* import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolKind import org.jetbrains.kotlin.descriptors.Modality +import org.jetbrains.kotlin.psi.KtDeclaration +import org.jetbrains.kotlin.psi.KtFunction class KSFunctionDeclarationImpl private constructor(private val ktFunctionSymbol: KtFunctionLikeSymbol) : KSFunctionDeclaration, @@ -89,8 +91,18 @@ class KSFunctionDeclarationImpl private constructor(private val ktFunctionSymbol return visitor.visitFunctionDeclaration(this, data) } - // TODO: Implement with PSI - override val declarations: Sequence<KSDeclaration> = emptySequence() + override val declarations: Sequence<KSDeclaration> by lazy { + val psi = ktFunctionSymbol.psi as? KtFunction ?: return@lazy emptySequence() + if (!psi.hasBlockBody()) { + emptySequence() + } else { + psi.bodyBlockExpression?.statements?.asSequence()?.filterIsInstance<KtDeclaration>()?.mapNotNull { + analyze { + it.getSymbol().toKSDeclaration() + } + } ?: emptySequence() + } + } override fun toString(): String { // TODO: fix origin for implicit Java constructor in AA diff --git a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSTypeImpl.kt b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSTypeImpl.kt index d8001b82..0ff11c58 100644 --- a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSTypeImpl.kt +++ b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSTypeImpl.kt @@ -26,7 +26,8 @@ import com.google.devtools.ksp.symbol.Nullability import org.jetbrains.kotlin.analysis.api.KtStarProjectionTypeArgument import org.jetbrains.kotlin.analysis.api.KtTypeArgumentWithVariance import org.jetbrains.kotlin.analysis.api.components.buildClassType -import org.jetbrains.kotlin.analysis.api.symbols.KtNamedClassOrObjectSymbol +import org.jetbrains.kotlin.analysis.api.symbols.KtClassOrObjectSymbol +import org.jetbrains.kotlin.analysis.api.symbols.KtTypeAliasSymbol import org.jetbrains.kotlin.analysis.api.types.KtClassErrorType import org.jetbrains.kotlin.analysis.api.types.KtFlexibleType import org.jetbrains.kotlin.analysis.api.types.KtFunctionalType @@ -44,10 +45,12 @@ class KSTypeImpl private constructor(internal val type: KtType) : KSType { private fun KtType.toDeclaration(): KSDeclaration { return analyze { when (this@toDeclaration) { - is KtNonErrorClassType -> - classId.getCorrespondingToplevelClassOrObjectSymbol() - .safeAs<KtNamedClassOrObjectSymbol>() - ?.let { KSClassDeclarationImpl.getCached(it) } ?: KSErrorTypeClassDeclaration + is KtNonErrorClassType -> { + when (val symbol = this@toDeclaration.classSymbol) { + is KtTypeAliasSymbol -> symbol.expandedType.toDeclaration() + is KtClassOrObjectSymbol -> KSClassDeclarationImpl.getCached(symbol) + } + } is KtClassErrorType -> KSErrorTypeClassDeclaration is KtFlexibleType -> type.lowerBoundIfFlexible().toDeclaration() diff --git a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSValueArgumentImpl.kt b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSValueArgumentImpl.kt index 3339b45e..087f3a92 100644 --- a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSValueArgumentImpl.kt +++ b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSValueArgumentImpl.kt @@ -19,7 +19,15 @@ package com.google.devtools.ksp.impl.symbol.kotlin import com.google.devtools.ksp.KSObjectCache import com.google.devtools.ksp.symbol.* +import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationApplicationValue +import org.jetbrains.kotlin.analysis.api.annotations.KtAnnotationValue +import org.jetbrains.kotlin.analysis.api.annotations.KtArrayAnnotationValue +import org.jetbrains.kotlin.analysis.api.annotations.KtConstantAnnotationValue +import org.jetbrains.kotlin.analysis.api.annotations.KtEnumEntryAnnotationValue +import org.jetbrains.kotlin.analysis.api.annotations.KtKClassAnnotationValue import org.jetbrains.kotlin.analysis.api.annotations.KtNamedAnnotationValue +import org.jetbrains.kotlin.analysis.api.annotations.KtUnsupportedAnnotationValue +import org.jetbrains.kotlin.analysis.api.symbols.KtNamedClassOrObjectSymbol class KSValueArgumentImpl private constructor( private val namedAnnotationValue: KtNamedAnnotationValue @@ -35,7 +43,7 @@ class KSValueArgumentImpl private constructor( override val isSpread: Boolean = false - override val value: Any = namedAnnotationValue.expression + override val value: Any? = namedAnnotationValue.expression.toValue() override val annotations: Sequence<KSAnnotation> = emptySequence() @@ -55,4 +63,35 @@ class KSValueArgumentImpl private constructor( override fun toString(): String { return "${name?.asString() ?: ""}:$value" } + + private fun KtAnnotationValue.toValue(): Any? = when (this) { + is KtArrayAnnotationValue -> this.values.map { it.toValue() } + is KtAnnotationApplicationValue -> KSAnnotationImpl.getCached(this.annotationValue) + is KtEnumEntryAnnotationValue -> this.callableId?.classId?.let { + analyze { + it.getCorrespondingToplevelClassOrObjectSymbol()?.let { + it.declarations().filterIsInstance<KSClassDeclarationEnumEntryImpl>().singleOrNull { + it.simpleName.asString() == this@toValue.callableId?.callableName?.asString() + } + } + } + } ?: KSErrorType + is KtKClassAnnotationValue -> { + val classDeclaration = when (this) { + is KtKClassAnnotationValue.KtNonLocalKClassAnnotationValue -> analyze { + (this@toValue.classId.getCorrespondingToplevelClassOrObjectSymbol() as? KtNamedClassOrObjectSymbol) + ?.let { KSClassDeclarationImpl.getCached(it) } + } + is KtKClassAnnotationValue.KtLocalKClassAnnotationValue -> analyze { + this@toValue.ktClass.getNamedClassOrObjectSymbol()?.let { + KSClassDeclarationImpl.getCached(it) + } + } + is KtKClassAnnotationValue.KtErrorClassAnnotationValue -> null + } + classDeclaration?.asStarProjectedType() ?: KSErrorType + } + is KtConstantAnnotationValue -> this.constantValue.value + is KtUnsupportedAnnotationValue -> null + } } diff --git a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/util.kt b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/util.kt index 395c6042..e0cf30d8 100644 --- a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/util.kt +++ b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/util.kt @@ -30,12 +30,15 @@ import org.jetbrains.kotlin.analysis.api.annotations.annotations import org.jetbrains.kotlin.analysis.api.lifetime.KtAlwaysAccessibleLifetimeTokenFactory import org.jetbrains.kotlin.analysis.api.symbols.KtClassOrObjectSymbol import org.jetbrains.kotlin.analysis.api.symbols.KtEnumEntrySymbol +import org.jetbrains.kotlin.analysis.api.symbols.KtFileSymbol import org.jetbrains.kotlin.analysis.api.symbols.KtFunctionLikeSymbol import org.jetbrains.kotlin.analysis.api.symbols.KtJavaFieldSymbol import org.jetbrains.kotlin.analysis.api.symbols.KtNamedClassOrObjectSymbol import org.jetbrains.kotlin.analysis.api.symbols.KtPropertySymbol import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol import org.jetbrains.kotlin.analysis.api.symbols.KtSymbolOrigin +import org.jetbrains.kotlin.analysis.api.symbols.KtTypeAliasSymbol +import org.jetbrains.kotlin.analysis.api.symbols.KtTypeParameterSymbol import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithMembers import org.jetbrains.kotlin.psi.KtElement @@ -145,3 +148,19 @@ internal fun KtSymbol.getContainingKSSymbol(): KSDeclaration? { } } } + +internal fun KtSymbol.toKSDeclaration(): KSDeclaration? = this.toKSNode() as? KSDeclaration + +internal fun KtSymbol.toKSNode(): KSNode { + return when (this) { + is KtPropertySymbol -> KSPropertyDeclarationImpl.getCached(this) + is KtNamedClassOrObjectSymbol -> KSClassDeclarationImpl.getCached(this) + is KtFunctionLikeSymbol -> KSFunctionDeclarationImpl.getCached(this) + is KtTypeAliasSymbol -> KSTypeAliasImpl.getCached(this) + is KtJavaFieldSymbol -> KSPropertyDeclarationJavaImpl.getCached(this) + is KtFileSymbol -> KSFileImpl.getCached(this) + is KtEnumEntrySymbol -> KSClassDeclarationEnumEntryImpl.getCached(this) + is KtTypeParameterSymbol -> KSTypeParameterImpl.getCached(this) + else -> throw IllegalStateException("Unexpected class for KtSymbol: ${this.javaClass}") + } +} diff --git a/kotlin-analysis-api/src/test/kotlin/com/google/devtools/ksp/impl/test/KSPAATest.kt b/kotlin-analysis-api/src/test/kotlin/com/google/devtools/ksp/impl/test/KSPAATest.kt index e666530b..bb55d1f7 100644 --- a/kotlin-analysis-api/src/test/kotlin/com/google/devtools/ksp/impl/test/KSPAATest.kt +++ b/kotlin-analysis-api/src/test/kotlin/com/google/devtools/ksp/impl/test/KSPAATest.kt @@ -86,10 +86,16 @@ class KSPAATest : AbstractKSPAATest() { } @Disabled - @TestMetadata("annotationValue.kt") + @TestMetadata("annotationValue_java.kt") @Test - fun testAnnotationValue() { - runTest("../compiler-plugin/testData/api/annotationValue.kt") + fun testAnnotationValue_java() { + runTest("../compiler-plugin/testData/api/annotationValue_java.kt") + } + + @TestMetadata("annotationValue_kt.kt") + @Test + fun testAnnotationValue_kt() { + runTest("../compiler-plugin/testData/api/annotationValue_kt.kt") } @Disabled diff --git a/test-utils/src/main/kotlin/com/google/devtools/ksp/processor/AnnotationArgumentProcessor.kt b/test-utils/src/main/kotlin/com/google/devtools/ksp/processor/AnnotationArgumentProcessor.kt index 3fd6634a..68e263c6 100644 --- a/test-utils/src/main/kotlin/com/google/devtools/ksp/processor/AnnotationArgumentProcessor.kt +++ b/test-utils/src/main/kotlin/com/google/devtools/ksp/processor/AnnotationArgumentProcessor.kt @@ -30,16 +30,15 @@ class AnnotationArgumentProcessor : AbstractTestProcessor() { override fun process(resolver: Resolver): List<KSAnnotated> { resolver.getSymbolsWithAnnotation("Bar", true).forEach { - val annotation = it.annotations.single() - annotation.arguments.forEach { it.accept(visitor, Unit) } + it.annotations.forEach { it.arguments.forEach { it.accept(visitor, Unit) } } } - val C = resolver.getClassDeclarationByName("C")!! - C.annotations.first().arguments.forEach { results.add(it.value.toString()) } - val ThrowsClass = resolver.getClassDeclarationByName("ThrowsClass")!! - ThrowsClass.declarations.filter { + val C = resolver.getClassDeclarationByName("C") + C?.annotations?.first()?.arguments?.forEach { results.add(it.value.toString()) } + val ThrowsClass = resolver.getClassDeclarationByName("ThrowsClass") + ThrowsClass?.declarations?.filter { it.simpleName.asString() == "throwsException" - }.forEach { + }?.forEach { it.annotations.single().annotationType.resolve().declaration.let { results.add(it.toString()) } |