Expose APIs to tell if a method param is synthetic.
Test: tested with XExecutableElementTest
Change-Id: I095d57a2f01c13d88d126952cca0767becf08067
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/XExecutableParameterElement.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/XExecutableParameterElement.kt
index b5148d4..8454bd9 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/XExecutableParameterElement.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/XExecutableParameterElement.kt
@@ -20,6 +20,21 @@
* Parameter of a method.
*/
interface XExecutableParameterElement : XVariableElement {
+ /**
+ * Returns `true` if this parameter is a synthetic Continuation parameter of a suspend function.
+ */
+ fun isContinuationParam(): Boolean
+
+ /**
+ * Returns `true` if this parameter represents the receiver of an extension function.
+ */
+ fun isReceiverParam(): Boolean
+
+ /**
+ * Returns `true` if this parameter represents the single parameter of a Kotlin property setter
+ * method.
+ */
+ fun isKotlinPropertyParam(): Boolean
/**
* The enclosing [XExecutableElement] this parameter belongs to.
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacMethodParameter.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacMethodParameter.kt
index 27aeaa5..88fe3b7 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacMethodParameter.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacMethodParameter.kt
@@ -30,6 +30,19 @@
kotlinMetadataFactory: () -> KmValueParameterContainer?,
val argIndex: Int
) : JavacVariableElement(env, element), XExecutableParameterElement {
+ override fun isContinuationParam() =
+ enclosingElement is JavacMethodElement &&
+ enclosingElement.isSuspendFunction() &&
+ enclosingElement.parameters.last() == this
+
+ override fun isReceiverParam() =
+ enclosingElement is JavacMethodElement &&
+ enclosingElement.isExtensionFunction() &&
+ enclosingElement.parameters.first() == this
+
+ override fun isKotlinPropertyParam() =
+ enclosingElement is JavacMethodElement &&
+ enclosingElement.isKotlinPropertyMethod()
override val kotlinMetadata by lazy { kotlinMetadataFactory() }
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspExecutableParameterElement.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspExecutableParameterElement.kt
index 8a6ed9a..fe11246 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspExecutableParameterElement.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspExecutableParameterElement.kt
@@ -36,6 +36,11 @@
) : KspElement(env, parameter),
XExecutableParameterElement,
XAnnotated by KspAnnotated.create(env, parameter, NO_USE_SITE_OR_METHOD_PARAMETER) {
+ override fun isContinuationParam() = false
+
+ override fun isReceiverParam() = false
+
+ override fun isKotlinPropertyParam() = false
override val name: String
get() = parameter.name?.asString() ?: "_no_param_name"
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/synthetic/KspSyntheticContinuationParameterElement.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/synthetic/KspSyntheticContinuationParameterElement.kt
index 620f91f..447fbf3 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/synthetic/KspSyntheticContinuationParameterElement.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/synthetic/KspSyntheticContinuationParameterElement.kt
@@ -48,6 +48,11 @@
delegate = null, // does not matter, this is synthetic and has no annotations.
filter = NO_USE_SITE
) {
+ override fun isContinuationParam() = true
+
+ override fun isReceiverParam() = false
+
+ override fun isKotlinPropertyParam() = false
override val name: String by lazy {
// KAPT uses `continuation` but it doesn't check for conflicts, we do.
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/synthetic/KspSyntheticPropertyMethodElement.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/synthetic/KspSyntheticPropertyMethodElement.kt
index d6bf00e..ec5190d 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/synthetic/KspSyntheticPropertyMethodElement.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/synthetic/KspSyntheticPropertyMethodElement.kt
@@ -232,6 +232,11 @@
delegate = enclosingElement.field.declaration.setter?.parameter,
filter = NO_USE_SITE_OR_SET_PARAM
) {
+ override fun isContinuationParam() = false
+
+ override fun isReceiverParam() = false
+
+ override fun isKotlinPropertyParam() = true
private val jvmTypeResolutionScope = KspJvmTypeResolutionScope.PropertySetterParameter(
declaration = enclosingElement
@@ -323,4 +328,4 @@
}
}
}
-}
\ No newline at end of file
+}
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/synthetic/KspSyntheticReceiverParameterElement.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/synthetic/KspSyntheticReceiverParameterElement.kt
index 1c7bf1e..acef3af 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/synthetic/KspSyntheticReceiverParameterElement.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/synthetic/KspSyntheticReceiverParameterElement.kt
@@ -42,6 +42,12 @@
filter = KspAnnotated.UseSiteFilter.NO_USE_SITE
) {
+ override fun isContinuationParam() = false
+
+ override fun isReceiverParam() = true
+
+ override fun isKotlinPropertyParam() = false
+
override val name: String by lazy {
// KAPT uses `$this$<functionName>`
"$" + "this" + "$" + enclosingElement.name
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XExecutableElementTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XExecutableElementTest.kt
index 73c87b1..91ff9e3 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XExecutableElementTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XExecutableElementTest.kt
@@ -445,6 +445,7 @@
assertThat(method.parameters.first().type.asTypeName()).isEqualTo(
String::class.asClassName()
)
+ assertThat(method.parameters.first().isKotlinPropertyParam()).isTrue()
assertThat(method.isPublic()).isTrue()
assertThat(method.parameters.first().type.nullability).isEqualTo(
XNullability.NONNULL
@@ -986,6 +987,7 @@
element.getDeclaredMethodByJvmName("ext1").let { method ->
assertThat(method.isExtensionFunction()).isTrue()
assertThat(method.parameters.size).isEqualTo(1)
+ assertThat(method.parameters[0].isReceiverParam()).isTrue()
assertThat(method.parameters[0].name).isEqualTo("\$this\$ext1")
assertThat(method.parameters[0].type.asTypeName())
.isEqualTo(String::class.asClassName())
@@ -1028,6 +1030,7 @@
assertThat(method.parameters.size).isEqualTo(2)
assertThat(method.parameters[0].type.asTypeName())
.isEqualTo(String::class.asClassName())
+ assertThat(method.parameters[1].isContinuationParam()).isTrue()
assertThat(method.parameters[1].type.typeName).isEqualTo(
ParameterizedTypeName.get(
ClassName.get("kotlin.coroutines", "Continuation"),