aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compiler-plugin/src/test/kotlin/com/google/devtools/ksp/test/KSPCompilerPluginTest.kt12
-rw-r--r--compiler-plugin/testData/api/annotationValue_java.kt (renamed from compiler-plugin/testData/api/annotationValue.kt)23
-rw-r--r--compiler-plugin/testData/api/annotationValue_kt.kt73
-rw-r--r--kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSAnnotationImpl.kt38
-rw-r--r--kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSClassDeclarationImpl.kt30
-rw-r--r--kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSFunctionDeclarationImpl.kt16
-rw-r--r--kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSTypeImpl.kt13
-rw-r--r--kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/KSValueArgumentImpl.kt41
-rw-r--r--kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/kotlin/util.kt19
-rw-r--r--kotlin-analysis-api/src/test/kotlin/com/google/devtools/ksp/impl/test/KSPAATest.kt12
-rw-r--r--test-utils/src/main/kotlin/com/google/devtools/ksp/processor/AnnotationArgumentProcessor.kt13
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())
}