add Resolver.getJvmCheckedException for property accessors
(cherry picked from commit 6bff3dc758c27e2ae601130a74a254b985d3e3f2)
diff --git a/api/src/main/kotlin/com/google/devtools/ksp/processing/Resolver.kt b/api/src/main/kotlin/com/google/devtools/ksp/processing/Resolver.kt
index 7d9f6db..ab94aa4 100644
--- a/api/src/main/kotlin/com/google/devtools/ksp/processing/Resolver.kt
+++ b/api/src/main/kotlin/com/google/devtools/ksp/processing/Resolver.kt
@@ -214,6 +214,14 @@
fun getJvmCheckedException(function: KSFunctionDeclaration): Sequence<KSType>
/**
+ * Returns checked exceptions declared in a property accessor's header.
+ * @return A sequence of [KSType] declared @Throws annotation for a Kotlin property accessor.
+ * Checked exceptions from class files are not supported yet, an empty sequence will be returned instead.
+ */
+ @KspExperimental
+ fun getJvmCheckedException(accessor: KSPropertyAccessor): Sequence<KSType>
+
+ /**
* Returns declarations with the given package name.
* @param packageName the package name to look up.
* @return A sequence of [KSDeclaration] with matching package name.
diff --git a/compiler-plugin/src/main/kotlin/com/google/devtools/ksp/processing/impl/ResolverImpl.kt b/compiler-plugin/src/main/kotlin/com/google/devtools/ksp/processing/impl/ResolverImpl.kt
index f155bf3..4560834 100644
--- a/compiler-plugin/src/main/kotlin/com/google/devtools/ksp/processing/impl/ResolverImpl.kt
+++ b/compiler-plugin/src/main/kotlin/com/google/devtools/ksp/processing/impl/ResolverImpl.kt
@@ -642,6 +642,17 @@
}
}
+ @SuppressWarnings("UNCHECKED_CAST")
+ private fun extractThrowsAnnotation(annotated: KSAnnotated): Sequence<KSType> {
+ return annotated.annotations
+ .singleOrNull {
+ it.shortName.asString() == "Throws" && it.annotationType.resolve().declaration.qualifiedName?.asString() == "kotlin.Throws"
+ }?.arguments
+ ?.singleOrNull()
+ ?.let { it.value as? ArrayList<KSType> }
+ ?.asSequence() ?: emptySequence()
+ }
+
@KspExperimental
override fun getJvmCheckedException(function: KSFunctionDeclaration): Sequence<KSType> {
return when (function.origin) {
@@ -650,15 +661,17 @@
psi.throwsList.referencedTypes.asSequence().map { getKSTypeCached(resolveJavaType(it)) }
}
Origin.KOTLIN -> {
- function.annotations
- .singleOrNull {
- it.shortName.asString() == "Throws" && it.annotationType.resolve().declaration.qualifiedName?.asString() == "kotlin.Throws"
- }
- ?.arguments
- ?.singleOrNull()
- ?.let { (it.value as? ArrayList<KSType>) }
- ?.asSequence()
- ?: emptySequence()
+ extractThrowsAnnotation(function)
+ }
+ else -> emptySequence()
+ }
+ }
+
+ @KspExperimental
+ override fun getJvmCheckedException(accessor: KSPropertyAccessor): Sequence<KSType> {
+ return when(accessor.origin) {
+ Origin.KOTLIN, Origin.SYNTHETIC -> {
+ extractThrowsAnnotation(accessor)
}
else -> emptySequence()
}
diff --git a/compiler-plugin/src/test/kotlin/com/google/devtools/ksp/processor/ThrowListProcessor.kt b/compiler-plugin/src/test/kotlin/com/google/devtools/ksp/processor/ThrowListProcessor.kt
index 4401b92..91e7665 100644
--- a/compiler-plugin/src/test/kotlin/com/google/devtools/ksp/processor/ThrowListProcessor.kt
+++ b/compiler-plugin/src/test/kotlin/com/google/devtools/ksp/processor/ThrowListProcessor.kt
@@ -5,6 +5,7 @@
import com.google.devtools.ksp.processing.Resolver
import com.google.devtools.ksp.symbol.KSAnnotated
import com.google.devtools.ksp.symbol.KSFunctionDeclaration
+import com.google.devtools.ksp.symbol.KSPropertyDeclaration
import com.google.devtools.ksp.symbol.KSType
@KspExperimental
@@ -20,6 +21,9 @@
val jlass = resolver.getClassDeclarationByName("ThrowsException")!!
result.add(resolver.getJvmCheckedException(klass.declarations.single { it.simpleName.asString() == "throwsKT" } as KSFunctionDeclaration).toResult())
result.add(resolver.getJvmCheckedException((jlass.declarations.single { it.simpleName.asString() == "foo" } as KSFunctionDeclaration)).toResult())
+ val propertyA = klass.declarations.single { it.simpleName.asString() == "a" } as KSPropertyDeclaration
+ result.add(resolver.getJvmCheckedException(propertyA.getter!!).toResult())
+ result.add(resolver.getJvmCheckedException(propertyA.setter!!).toResult())
return emptyList()
}
diff --git a/compiler-plugin/testData/api/throwList.kt b/compiler-plugin/testData/api/throwList.kt
index 2ae975f..ae11e41 100644
--- a/compiler-plugin/testData/api/throwList.kt
+++ b/compiler-plugin/testData/api/throwList.kt
@@ -20,6 +20,8 @@
// EXPECTED:
// java.io.IOException,java.util.NoSuchElementException
// java.io.IOException,java.lang.IndexOutOfBoundsException
+// java.io.IOException,java.util.NoSuchElementException
+// java.lang.IndexOutOfBoundsException
// END
// FILE: ThrowsException.java
import java.io.IOException;
@@ -34,4 +36,14 @@
class ThrowsKt {
@Throws(java.io.IOException::class, java.util.NoSuchElementException::class)
fun throwsKT()
-}
\ No newline at end of file
+
+ @set:Throws(java.lang.IndexOutOfBoundsException::class)
+ var a: Int
+ @Throws(java.io.IOException::class, java.util.NoSuchElementException::class)
+ get() {
+ return 1
+ }
+ set(a: Int) {
+
+ }
+}