diff --git a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/java/KSValueArgumentLiteImpl.kt b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/java/KSValueArgumentLiteImpl.kt index b8413870a3..e34805ff47 100644 --- a/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/java/KSValueArgumentLiteImpl.kt +++ b/kotlin-analysis-api/src/main/kotlin/com/google/devtools/ksp/impl/symbol/java/KSValueArgumentLiteImpl.kt @@ -2,6 +2,7 @@ package com.google.devtools.ksp.impl.symbol.java import com.google.devtools.ksp.common.IdKeyPair import com.google.devtools.ksp.common.KSObjectCache +import com.google.devtools.ksp.impl.symbol.kotlin.AbstractKSValueArgumentImpl import com.google.devtools.ksp.symbol.* class KSValueArgumentLiteImpl private constructor( @@ -10,7 +11,7 @@ class KSValueArgumentLiteImpl private constructor( override val parent: KSNode, override val origin: Origin, override val location: Location -) : KSValueArgument { +) : AbstractKSValueArgumentImpl() { companion object : KSObjectCache, KSValueArgumentLiteImpl>() { fun getCached( name: KSName?, @@ -25,12 +26,4 @@ class KSValueArgumentLiteImpl private constructor( override val isSpread: Boolean = false override val annotations: Sequence = emptySequence() - - override fun toString(): String { - return "${name?.asString() ?: ""}:$value" - } - - override fun accept(visitor: KSVisitor, data: D): R { - return visitor.visitValueArgument(this, data) - } } 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 c776bf5825..ed72a9930d 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 @@ -26,7 +26,7 @@ class KSValueArgumentImpl private constructor( private val namedAnnotationValue: KaNamedAnnotationValue, override val parent: KSNode?, override val origin: Origin -) : KSValueArgument, Deferrable { +) : AbstractKSValueArgumentImpl(), Deferrable { companion object : KSObjectCache() { fun getCached(namedAnnotationValue: KaNamedAnnotationValue, parent: KSNode?, origin: Origin) = cache.getOrPut(namedAnnotationValue) { @@ -48,6 +48,24 @@ class KSValueArgumentImpl private constructor( namedAnnotationValue.expression.sourcePsi?.toLocation() ?: NonExistLocation } + override fun defer(): Restorable { + val parent = if (parent is Deferrable) parent.defer() else null + return Restorable { getCached(namedAnnotationValue, parent?.restore(), origin) } + } +} + +abstract class AbstractKSValueArgumentImpl : KSValueArgument { + override fun hashCode(): Int { + return name.hashCode() * 31 + value.hashCode() + } + + override fun equals(other: Any?): Boolean { + if (other !is KSValueArgument) + return false + + return other.name == this.name && other.value == this.value + } + override fun accept(visitor: KSVisitor, data: D): R { return visitor.visitValueArgument(this, data) } @@ -55,9 +73,4 @@ class KSValueArgumentImpl private constructor( override fun toString(): String { return "${name?.asString() ?: ""}:$value" } - - override fun defer(): Restorable { - val parent = if (parent is Deferrable) parent.defer() else null - return Restorable { getCached(namedAnnotationValue, parent?.restore(), origin) } - } } diff --git a/kotlin-analysis-api/testData/annotationValue/annotationValue_kt.kt b/kotlin-analysis-api/testData/annotationValue/annotationValue_kt.kt index 94aa857acd..50423cbc76 100644 --- a/kotlin-analysis-api/testData/annotationValue/annotationValue_kt.kt +++ b/kotlin-analysis-api/testData/annotationValue/annotationValue_kt.kt @@ -43,6 +43,22 @@ // TestNestedAnnotationDefaults: hij // TestNestedAnnotationDefaults: def // TestNestedAnnotationDefaults: hij +// @JavaAnnotationWithDefaultsInSource(value:def) == @JavaAnnotationWithDefaultsInSource(value:def): true +// @JavaAnnotationWithDefaultsInSource(value:def) == @KotlinAnnotationWithDefaultsInSource(value:hij): false +// @JavaAnnotationWithDefaultsInSource(value:def) == @JavaAnnotationWithDefaults(value:def): true +// @JavaAnnotationWithDefaultsInSource(value:def) == @KotlinAnnotationWithDefaults(value:hij): false +// @KotlinAnnotationWithDefaultsInSource(value:hij) == @JavaAnnotationWithDefaultsInSource(value:def): false +// @KotlinAnnotationWithDefaultsInSource(value:hij) == @KotlinAnnotationWithDefaultsInSource(value:hij): true +// @KotlinAnnotationWithDefaultsInSource(value:hij) == @JavaAnnotationWithDefaults(value:def): false +// @KotlinAnnotationWithDefaultsInSource(value:hij) == @KotlinAnnotationWithDefaults(value:hij): true +// @JavaAnnotationWithDefaults(value:def) == @JavaAnnotationWithDefaultsInSource(value:def): true +// @JavaAnnotationWithDefaults(value:def) == @KotlinAnnotationWithDefaultsInSource(value:hij): false +// @JavaAnnotationWithDefaults(value:def) == @JavaAnnotationWithDefaults(value:def): true +// @JavaAnnotationWithDefaults(value:def) == @KotlinAnnotationWithDefaults(value:hij): false +// @KotlinAnnotationWithDefaults(value:hij) == @JavaAnnotationWithDefaultsInSource(value:def): false +// @KotlinAnnotationWithDefaults(value:hij) == @KotlinAnnotationWithDefaultsInSource(value:hij): true +// @KotlinAnnotationWithDefaults(value:hij) == @JavaAnnotationWithDefaults(value:def): false +// @KotlinAnnotationWithDefaults(value:hij) == @KotlinAnnotationWithDefaults(value:hij): true // END // MODULE: module1 // FILE: placeholder.kt @@ -169,3 +185,10 @@ annotation class KotlinAnnotationWithDefaultsInSource(val otherAnnotation: Other @JavaAnnotationWithDefaults @KotlinAnnotationWithDefaults class TestNestedAnnotationDefaults {} + +// FILE: TestValueArgEquals.java +@JavaAnnotationWithDefaultsInSource +@KotlinAnnotationWithDefaultsInSource +@JavaAnnotationWithDefaults +@KotlinAnnotationWithDefaults +class TestValueArgEquals {} diff --git a/kotlin-analysis-api/testData/parent.kt b/kotlin-analysis-api/testData/parent.kt index 379b4db8f5..afbd846663 100644 --- a/kotlin-analysis-api/testData/parent.kt +++ b/kotlin-analysis-api/testData/parent.kt @@ -82,7 +82,6 @@ // parent of topProp.getter(): topProp // parent of Anno: Anno // parent of Anno: @Anno -// parent of param:: @Anno // parent of @Anno: topProp // parent of topProp: File: a.kt // parent of T: T @@ -91,7 +90,6 @@ // parent of T: topFun // parent of Anno: Anno // parent of Anno: @Anno -// parent of param:: @Anno // parent of @Anno: topFun // parent of topFun: File: a.kt // parent of Annotation: Annotation @@ -125,7 +123,6 @@ // parent of ITF: topClass // parent of Anno: Anno // parent of Anno: @Anno -// parent of param:: @Anno // parent of @Anno: topClass // parent of topClass: File: a.kt // parent of Int: Int 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 ef6c682225..0f4d133ef0 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 @@ -99,6 +99,17 @@ class AnnotationArgumentProcessor : AbstractTestProcessor() { } } + resolver.getClassDeclarationByName("TestValueArgEquals")?.let { cls -> + cls.annotations.forEach { anno1 -> + val arg1 = (anno1.arguments.single().value as KSAnnotation).arguments.single() + cls.annotations.forEach { anno2 -> + val arg2 = (anno2.arguments.single().value as KSAnnotation).arguments.single() + val eq = arg1 == arg2 + results.add("$anno1($arg1) == $anno2($arg2): $eq") + } + } + } + return emptyList() }