Update KSP to beta01 and KCT to 1.4.1
* KSP beta01 introduces an api change in function overrides where it can
handle cases when a java method overrides a kotlin property. This also
means the return type of `KSFunction.findOverridee` is a KSDeclaration
instead of KSFunction. We use this when resolving types so I've updated
Room to expect a property declaration as well. It was also affecting
override variance resolution but that code only ever runs for kotlin
sources so it was not necessary to handle property overrides there.
* Adding more tests to java overriding kotlin property revelated another
bug where we were setting an invalid parameter name for property setter
values. (<set-?>). That name is valid in byte code but not in source
code. I've updated JavacVariableElement and KotlinSynthetic to use a
sanitized name instead. We could've done it while generating code but
since many other things refer to these parameters, it is safer to do it
while parsing parameters and hide the detail from the rest of the
processing.
* One of the new tests I've added hit a bug in KSP that revelated after
KSP fixed "java method overrides kotlin property" case. Added a try
catch helper for it:
https://github.com/google/ksp/issues/462
* Previously, when listing methods in a kotlin class, we always listed
setters before getters which made the source code match tests slightly
more difficult. Changed it to keep setter/getter of a property together
in the methods list.
* KSP changed its processor provider interface, updated Room
accordingly. (it now receives 1 container object instead of multiple
parameters)
Bug: 160322705
Test: existing tests + more tests for overrides
Change-Id: I92ec446b59cdeccc37bd91308d1a20acf3fe959a
diff --git a/buildSrc/src/main/kotlin/androidx/build/dependencies/Dependencies.kt b/buildSrc/src/main/kotlin/androidx/build/dependencies/Dependencies.kt
index fbb8c91..2b93c79 100644
--- a/buildSrc/src/main/kotlin/androidx/build/dependencies/Dependencies.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/dependencies/Dependencies.kt
@@ -78,8 +78,8 @@
const val JSR250 = "javax.annotation:javax.annotation-api:1.2"
const val JUNIT = "junit:junit:4.12"
const val KOTLINPOET = "com.squareup:kotlinpoet:1.8.0"
-const val KOTLIN_COMPILE_TESTING = "com.github.tschuchortdev:kotlin-compile-testing:1.4.0"
-const val KOTLIN_COMPILE_TESTING_KSP = "com.github.tschuchortdev:kotlin-compile-testing-ksp:1.4.0"
+const val KOTLIN_COMPILE_TESTING = "com.github.tschuchortdev:kotlin-compile-testing:1.4.1"
+const val KOTLIN_COMPILE_TESTING_KSP = "com.github.tschuchortdev:kotlin-compile-testing-ksp:1.4.1"
/**
* KSP is used both as a plugin and runtime dependency, hence its version is declared in the
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 5493c52..b46dca2 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -21,9 +21,9 @@
hilt = "2.36"
incap = "0.2"
kotlin = "1.5.10"
-kotlinCompileTesting = "1.4.0"
+kotlinCompileTesting = "1.4.1"
kotlinCoroutines = "1.4.3"
-ksp = "1.5.0-1.0.0-alpha10"
+ksp = "1.5.10-1.0.0-beta01"
leakcanary = "2.2"
mockito = "2.25.0"
sqldelight = "1.3.0"
diff --git a/room/compiler-processing-testing/src/main/java/androidx/room/compiler/processing/SyntheticKspProcessor.kt b/room/compiler-processing-testing/src/main/java/androidx/room/compiler/processing/SyntheticKspProcessor.kt
index a179a1c..d364947 100644
--- a/room/compiler-processing-testing/src/main/java/androidx/room/compiler/processing/SyntheticKspProcessor.kt
+++ b/room/compiler-processing-testing/src/main/java/androidx/room/compiler/processing/SyntheticKspProcessor.kt
@@ -20,6 +20,7 @@
import com.google.devtools.ksp.processing.KSPLogger
import com.google.devtools.ksp.processing.Resolver
import com.google.devtools.ksp.processing.SymbolProcessor
+import com.google.devtools.ksp.processing.SymbolProcessorEnvironment
import com.google.devtools.ksp.processing.SymbolProcessorProvider
import com.google.devtools.ksp.symbol.KSAnnotated
@@ -71,16 +72,11 @@
private class Provider(
private val delegate: SyntheticKspProcessor
) : SymbolProcessorProvider {
- override fun create(
- options: Map<String, String>,
- kotlinVersion: KotlinVersion,
- codeGenerator: CodeGenerator,
- logger: KSPLogger
- ): SymbolProcessor {
+ override fun create(environment: SymbolProcessorEnvironment): SymbolProcessor {
delegate.internalInit(
- options = options,
- codeGenerator = codeGenerator,
- logger = logger
+ options = environment.options,
+ codeGenerator = environment.codeGenerator,
+ logger = environment.logger
)
return delegate
}
diff --git a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacExecutableElement.kt b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacExecutableElement.kt
index 3473ba1..ea9c18a 100644
--- a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacExecutableElement.kt
+++ b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacExecutableElement.kt
@@ -45,7 +45,8 @@
executable = this,
containing = containing,
element = variable,
- kotlinMetadata = kotlinMetadata?.parameters?.getOrNull(index)
+ kotlinMetadata = kotlinMetadata?.parameters?.getOrNull(index),
+ argIndex = index
)
}
}
diff --git a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacMethodParameter.kt b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacMethodParameter.kt
index 01fcd68..71cb24c 100644
--- a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacMethodParameter.kt
+++ b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacMethodParameter.kt
@@ -18,6 +18,7 @@
import androidx.room.compiler.processing.javac.kotlin.KmType
import androidx.room.compiler.processing.javac.kotlin.KmValueParameter
+import androidx.room.compiler.processing.util.sanitizeAsJavaParameterName
import javax.lang.model.element.VariableElement
internal class JavacMethodParameter(
@@ -25,10 +26,13 @@
private val executable: JavacExecutableElement,
containing: JavacTypeElement,
element: VariableElement,
- val kotlinMetadata: KmValueParameter?
+ val kotlinMetadata: KmValueParameter?,
+ val argIndex: Int
) : JavacVariableElement(env, containing, element) {
override val name: String
- get() = kotlinMetadata?.name ?: super.name
+ get() = (kotlinMetadata?.name ?: super.name).sanitizeAsJavaParameterName(
+ argIndex = argIndex
+ )
override val kotlinType: KmType?
get() = kotlinMetadata?.type
override val fallbackLocationText: String
diff --git a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KSAsMemberOf.kt b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KSAsMemberOf.kt
index 53cd24a..1fd802b 100644
--- a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KSAsMemberOf.kt
+++ b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KSAsMemberOf.kt
@@ -16,10 +16,13 @@
package androidx.room.compiler.processing.ksp
+import com.google.devtools.ksp.symbol.KSFunction
import com.google.devtools.ksp.symbol.KSFunctionDeclaration
import com.google.devtools.ksp.symbol.KSPropertyDeclaration
import com.google.devtools.ksp.symbol.KSType
+import com.google.devtools.ksp.symbol.KSTypeParameter
import com.google.devtools.ksp.symbol.KSValueParameter
+import java.lang.UnsupportedOperationException
/**
* Returns the type of a property as if it is member of the given [ksType].
@@ -64,7 +67,7 @@
if (ksType == null) {
return resolved
}
- val asMember = functionDeclaration.asMemberOf(
+ val asMember = functionDeclaration.safeAsMemberOf(
containing = ksType
)
// TODO b/173224718
@@ -86,8 +89,42 @@
// object
resolved
}
- else -> this.asMemberOf(
+ else -> this.safeAsMemberOf(
containing = ksType
).returnType
} ?: error("cannot find return type for $this")
}
+
+/**
+ * Runs asMemberOf while working around a KSP bug where if a java method overrides a property,
+ * calling as member of fails it.
+ */
+private fun KSFunctionDeclaration.safeAsMemberOf(
+ containing: KSType
+): KSFunction {
+ return try {
+ asMemberOf(containing)
+ } catch (unsupported: UnsupportedOperationException) {
+ SyntheticKSFunction(this)
+ }
+}
+
+/**
+ * Workaround for https://github.com/google/ksp/issues/462
+ */
+private class SyntheticKSFunction(
+ val declaration: KSFunctionDeclaration
+) : KSFunction {
+ override val extensionReceiverType: KSType?
+ get() = declaration.extensionReceiver?.resolve()
+ override val isError: Boolean
+ get() = false
+ override val parameterTypes: List<KSType?>
+ get() = declaration.parameters.map { param ->
+ param.type.resolve()
+ }
+ override val returnType: KSType?
+ get() = declaration.returnType?.resolve()
+ override val typeParameters: List<KSTypeParameter>
+ get() = declaration.typeParameters
+}
\ No newline at end of file
diff --git a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KSFunctionExt.kt b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KSFunctionExt.kt
new file mode 100644
index 0000000..76e7323
--- /dev/null
+++ b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KSFunctionExt.kt
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * 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.
+ */
+
+package androidx.room.compiler.processing.ksp
+
+import androidx.room.compiler.processing.XType
+import com.google.devtools.ksp.symbol.KSFunctionDeclaration
+import com.google.devtools.ksp.symbol.KSPropertyDeclaration
+
+/**
+ * A custom ReturnType that return an [XType] while also resolving boxing if necessary (might happen
+ * due to overrides).
+ */
+internal fun KSFunctionDeclaration.returnXType(
+ env: KspProcessingEnv,
+ containing: KspType?
+): XType {
+ // b/160258066
+ // we may need to box the return type if it is overriding a generic, hence, we should
+ // use the declaration of the overridee if available when deciding nullability
+ val overridee = this.findOverridee()
+ // when a java method overrides a property, overridee might be a property instead
+ // of a function.
+ val originatingReference = when (overridee) {
+ is KSFunctionDeclaration -> overridee.returnType
+ is KSPropertyDeclaration -> {
+ overridee.type
+ }
+ null -> null
+ else -> error(
+ """
+ Unexpected overridee type for $this ($overridee).
+ Please file a bug with steps to reproduce.
+ https://issuetracker.google.com/issues/new?component=413107
+ """.trimIndent()
+ )
+ } ?: returnType
+ return env.wrap(
+ originatingReference = checkNotNull(originatingReference),
+ ksType = returnTypeAsMemberOf(
+ ksType = containing?.ksType
+ )
+ )
+}
\ No newline at end of file
diff --git a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspMethodElement.kt b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspMethodElement.kt
index ab5e1ae..22811c2 100644
--- a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspMethodElement.kt
+++ b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspMethodElement.kt
@@ -96,15 +96,9 @@
env, containing, declaration
) {
override val returnType: XType by lazy {
- // b/160258066
- // we may need to box the return type if it is overriding a generic, hence, we should
- // use the declaration of the overridee if available when deciding nullability
- val overridee = declaration.findOverridee()
- env.wrap(
- ksType = declaration.returnTypeAsMemberOf(
- ksType = containing.type?.ksType
- ),
- originatingReference = checkNotNull(overridee?.returnType ?: declaration.returnType)
+ declaration.returnXType(
+ env = env,
+ containing = containing.type
)
}
override fun isSuspendFunction() = false
diff --git a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspMethodType.kt b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspMethodType.kt
index 73f1dfc..7907934 100644
--- a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspMethodType.kt
+++ b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspMethodType.kt
@@ -65,15 +65,9 @@
containing: KspType?
) : KspMethodType(env, origin, containing) {
override val returnType: XType by lazy {
- // b/160258066
- // we may need to box the return type if it is overriding a generic, hence, we should
- // use the declaration of the overridee if available when deciding nullability
- val overridee = origin.declaration.findOverridee()
- env.wrap(
- originatingReference = (overridee?.returnType ?: origin.declaration.returnType)!!,
- ksType = origin.declaration.returnTypeAsMemberOf(
- ksType = containing?.ksType
- )
+ origin.declaration.returnXType(
+ env = env,
+ containing = containing
)
}
}
diff --git a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspTypeElement.kt b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspTypeElement.kt
index bd010f7..6918e65 100644
--- a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspTypeElement.kt
+++ b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspTypeElement.kt
@@ -168,11 +168,11 @@
}
private val syntheticGetterSetterMethods: List<XMethodElement> by lazy {
- val setters = _declaredProperties.mapNotNull {
+ _declaredProperties.flatMap {
if (it.type.ksType.isInline()) {
// KAPT does not generate getters/setters for inlines, we'll hide them as well
// until room generates kotlin code
- return@mapNotNull null
+ return@flatMap emptyList()
}
val setter = it.declaration.setter
@@ -191,21 +191,6 @@
}
else -> it.declaration.isMutable
}
- if (needsSetter) {
- KspSyntheticPropertyMethodElement.Setter(
- env = env,
- field = it
- )
- } else {
- null
- }
- }
- val getters = _declaredProperties.mapNotNull {
- if (it.type.ksType.isInline()) {
- // KAPT does not generate getters/setters for inlines, we'll hide them as well
- // until room generates kotlin code
- return@mapNotNull null
- }
val getter = it.declaration.getter
val needsGetter = when {
it.declaration.hasJvmFieldAnnotation() -> {
@@ -222,8 +207,15 @@
}
else -> true
}
-
- if (needsGetter) {
+ val setterElm = if (needsSetter) {
+ KspSyntheticPropertyMethodElement.Setter(
+ env = env,
+ field = it
+ )
+ } else {
+ null
+ }
+ val getterElm = if (needsGetter) {
KspSyntheticPropertyMethodElement.Getter(
env = env,
field = it
@@ -231,8 +223,8 @@
} else {
null
}
+ listOfNotNull(getterElm, setterElm)
}
- setters + getters
}
override fun isInterface(): Boolean {
diff --git a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/OverrideVarianceResolver.kt b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/OverrideVarianceResolver.kt
index 159d90d..96cade3 100644
--- a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/OverrideVarianceResolver.kt
+++ b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/OverrideVarianceResolver.kt
@@ -22,6 +22,7 @@
import com.google.devtools.ksp.isOpen
import com.google.devtools.ksp.symbol.ClassKind
import com.google.devtools.ksp.symbol.KSClassDeclaration
+import com.google.devtools.ksp.symbol.KSFunctionDeclaration
import com.google.devtools.ksp.symbol.KSType
import com.google.devtools.ksp.symbol.KSTypeArgument
import com.google.devtools.ksp.symbol.KSTypeParameter
@@ -90,11 +91,16 @@
// if declared in the same class, skip
return null
}
+
// it is declared in a super type, get that
+ val overridee = funDeclaration.findOverridee() as? KSFunctionDeclaration
+ // in kotlin, a method cannot override a property and we get to this code only for kotlin,
+ // hence we only check for overridee if it is a KSFunction. Override is KSDeclaration by
+ // default to handle cases when a Java method overrides a kotlin property
val overrideeElm = KspMethodElement.create(
env = env,
containing = env.wrapClassDeclaration(declaredIn),
- declaration = funDeclaration.findOverridee() ?: funDeclaration
+ declaration = overridee ?: funDeclaration
)
val containing = overrideeElm.enclosingElement.type ?: return null
return KspMethodType.create(
diff --git a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/synthetic/KspSyntheticPropertyMethodElement.kt b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/synthetic/KspSyntheticPropertyMethodElement.kt
index 55bfae1..b5636fa 100644
--- a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/synthetic/KspSyntheticPropertyMethodElement.kt
+++ b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/synthetic/KspSyntheticPropertyMethodElement.kt
@@ -35,6 +35,7 @@
import androidx.room.compiler.processing.ksp.KspTypeElement
import androidx.room.compiler.processing.ksp.findEnclosingMemberContainer
import androidx.room.compiler.processing.ksp.overrides
+import androidx.room.compiler.processing.util.sanitizeAsJavaParameterName
import com.google.devtools.ksp.KspExperimental
import com.google.devtools.ksp.symbol.KSPropertyAccessor
import com.google.devtools.ksp.symbol.KSPropertyGetter
@@ -222,7 +223,8 @@
) {
override val name: String by lazy {
- origin.field.declaration.setter?.parameter?.name?.asString() ?: "value"
+ val originalName = origin.field.declaration.setter?.parameter?.name?.asString()
+ originalName.sanitizeAsJavaParameterName(0)
}
override val type: XType
get() = origin.field.type
diff --git a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/util/NamingUtils.kt b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/util/NamingUtils.kt
new file mode 100644
index 0000000..1d96f2d
--- /dev/null
+++ b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/util/NamingUtils.kt
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * 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.
+ */
+
+package androidx.room.compiler.processing.util
+
+import javax.lang.model.SourceVersion
+
+/**
+ * Kotlin might generate names that are not valid in Java source code (but valid in binary).
+ * This helper method is used to sanitize them for method parameters.
+ */
+internal fun String?.sanitizeAsJavaParameterName(
+ argIndex: Int
+): String = if (this != null && SourceVersion.isName(this)) {
+ this
+} else {
+ "arg$argIndex"
+}
\ No newline at end of file
diff --git a/room/compiler-processing/src/test/java/androidx/room/compiler/processing/FallbackLocationInformationTest.kt b/room/compiler-processing/src/test/java/androidx/room/compiler/processing/FallbackLocationInformationTest.kt
index 0a358dd..cd71d87 100644
--- a/room/compiler-processing/src/test/java/androidx/room/compiler/processing/FallbackLocationInformationTest.kt
+++ b/room/compiler-processing/src/test/java/androidx/room/compiler/processing/FallbackLocationInformationTest.kt
@@ -109,7 +109,7 @@
assertThat(
propSetter.parameters.first().fallbackLocationText
).isEqualTo(
- "<set-?> in foo.bar.KotlinSubject.setProp(java.lang.String)"
+ "arg0 in foo.bar.KotlinSubject.setProp(java.lang.String)"
)
}
diff --git a/room/compiler-processing/src/test/java/androidx/room/compiler/processing/MethodSpecHelperTest.kt b/room/compiler-processing/src/test/java/androidx/room/compiler/processing/MethodSpecHelperTest.kt
index e32bfa0..3e6dd30 100644
--- a/room/compiler-processing/src/test/java/androidx/room/compiler/processing/MethodSpecHelperTest.kt
+++ b/room/compiler-processing/src/test/java/androidx/room/compiler/processing/MethodSpecHelperTest.kt
@@ -328,8 +328,61 @@
overridesCheck(source, impl)
}
+ @Test
+ fun javaOverridesKotlinProperty() {
+ val myInterface = Source.kotlin(
+ "MyInterface.kt",
+ """
+ package foo.bar
+ interface MyInterface {
+ val x:Int
+ var y:Int
+ }
+ """.trimIndent()
+ )
+ val javaImpl = Source.java(
+ "foo.bar.Baz",
+ """
+ package foo.bar;
+ class Baz implements MyInterface {
+ public int getX() {
+ return 1;
+ }
+ public int getY() {
+ return 1;
+ }
+ public void setY(int value) {
+ }
+ }
+ """.trimIndent()
+ )
+ overridesCheck(myInterface, javaImpl)
+ }
+
+ @Test
+ fun kotlinOverridesKotlinProperty() {
+ val source = Source.kotlin(
+ "MyInterface.kt",
+ """
+ package foo.bar
+ interface MyInterface {
+ var x:Int
+ }
+ open class Baz : MyInterface {
+ override var x: Int
+ get() = TODO("not implemented")
+ set(value) {}
+ }
+ """.trimIndent()
+ )
+ overridesCheck(source)
+ }
+
@Suppress("NAME_SHADOWING") // intentional
- private fun overridesCheck(vararg sources: Source, ignoreInheritedMethods: Boolean = false) {
+ private fun overridesCheck(
+ vararg sources: Source,
+ ignoreInheritedMethods: Boolean = false
+ ) {
val (sources: List<Source>, classpath: List<File>) = if (preCompiledCode) {
emptyList<Source>() to listOf(compileFiles(sources.toList()))
} else {
diff --git a/room/compiler-processing/src/test/java/androidx/room/compiler/processing/XExecutableElementTest.kt b/room/compiler-processing/src/test/java/androidx/room/compiler/processing/XExecutableElementTest.kt
index 39fb06c..fa72243 100644
--- a/room/compiler-processing/src/test/java/androidx/room/compiler/processing/XExecutableElementTest.kt
+++ b/room/compiler-processing/src/test/java/androidx/room/compiler/processing/XExecutableElementTest.kt
@@ -511,6 +511,90 @@
}
@Test
+ fun javaMethodOverridesKotlinProperty() {
+ val myInterface = Source.kotlin(
+ "MyInterface.kt",
+ """
+ interface MyInterface {
+ val x:Int
+ var y:Int
+ }
+ """.trimIndent()
+ )
+ val javaImpl = Source.java(
+ "JavaImpl",
+ """
+ class JavaImpl implements MyInterface {
+ public int getX() {
+ return 1;
+ }
+ public int getY() {
+ return 1;
+ }
+ public void setY(int value) {
+ }
+ }
+ """.trimIndent()
+ )
+ runProcessorTest(
+ sources = listOf(myInterface, javaImpl)
+ ) { invocation ->
+ val elm = invocation.processingEnv.requireTypeElement("JavaImpl")
+ assertThat(
+ elm.getMethod("getX").returnType.typeName
+ ).isEqualTo(TypeName.INT)
+ assertThat(
+ elm.getMethod("getY").returnType.typeName
+ ).isEqualTo(TypeName.INT)
+ assertThat(
+ elm.getMethod("setY").parameters.first().type.typeName
+ ).isEqualTo(TypeName.INT)
+ }
+ }
+
+ @Test
+ fun javaMethodOverridesKotlinProperty_generic() {
+ val myInterface = Source.kotlin(
+ "MyInterface.kt",
+ """
+ interface MyInterface<T> {
+ val x:T
+ var y:T
+ }
+ """.trimIndent()
+ )
+ val javaImpl = Source.java(
+ "JavaImpl",
+ """
+ class JavaImpl implements MyInterface<Integer> {
+ public Integer getX() {
+ return 1;
+ }
+ public Integer getY() {
+ return 1;
+ }
+ public void setY(Integer value) {
+ }
+ }
+ """.trimIndent()
+ )
+ runProcessorTest(
+ sources = listOf(myInterface, javaImpl)
+ ) { invocation ->
+ val elm = invocation.processingEnv.requireTypeElement("JavaImpl")
+ assertThat(
+ elm.getMethod("getX").returnType.typeName
+ ).isEqualTo(TypeName.INT.box())
+ assertThat(
+ elm.getMethod("getY").returnType.typeName
+ ).isEqualTo(TypeName.INT.box())
+ assertThat(
+ elm.getMethod("setY").parameters.first().type.typeName
+ ).isEqualTo(TypeName.INT.box())
+ }
+ }
+
+ @Test
fun genericToPrimitiveOverrides_methodElement() {
genericToPrimitiveOverrides(asMemberOf = false)
}
diff --git a/room/compiler-processing/src/test/java/androidx/room/compiler/processing/XProcessingStepTest.kt b/room/compiler-processing/src/test/java/androidx/room/compiler/processing/XProcessingStepTest.kt
index a961ffd..004ace1 100644
--- a/room/compiler-processing/src/test/java/androidx/room/compiler/processing/XProcessingStepTest.kt
+++ b/room/compiler-processing/src/test/java/androidx/room/compiler/processing/XProcessingStepTest.kt
@@ -24,10 +24,9 @@
import com.google.auto.common.BasicAnnotationProcessor
import com.google.common.truth.Truth.assertAbout
import com.google.common.truth.Truth.assertThat
-import com.google.devtools.ksp.processing.CodeGenerator
-import com.google.devtools.ksp.processing.KSPLogger
import com.google.devtools.ksp.processing.Resolver
import com.google.devtools.ksp.processing.SymbolProcessor
+import com.google.devtools.ksp.processing.SymbolProcessorEnvironment
import com.google.devtools.ksp.processing.SymbolProcessorProvider
import com.google.devtools.ksp.symbol.ClassKind
import com.google.devtools.ksp.symbol.KSAnnotated
@@ -315,19 +314,14 @@
}
var returned: List<KSAnnotated>? = null
val processorProvider = object : SymbolProcessorProvider {
- override fun create(
- options: Map<String, String>,
- kotlinVersion: KotlinVersion,
- codeGenerator: CodeGenerator,
- logger: KSPLogger
- ): SymbolProcessor {
+ override fun create(environment: SymbolProcessorEnvironment): SymbolProcessor {
return object : SymbolProcessor {
override fun process(resolver: Resolver): List<KSAnnotated> {
val env = XProcessingEnv.create(
emptyMap(),
resolver,
- codeGenerator,
- logger
+ environment.codeGenerator,
+ environment.logger
)
return processingStep.executeInKsp(env)
.also { returned = it }
diff --git a/room/compiler/src/main/kotlin/androidx/room/RoomKspProcessor.kt b/room/compiler/src/main/kotlin/androidx/room/RoomKspProcessor.kt
index d28541f..fa1656b9 100644
--- a/room/compiler/src/main/kotlin/androidx/room/RoomKspProcessor.kt
+++ b/room/compiler/src/main/kotlin/androidx/room/RoomKspProcessor.kt
@@ -22,6 +22,7 @@
import com.google.devtools.ksp.processing.KSPLogger
import com.google.devtools.ksp.processing.Resolver
import com.google.devtools.ksp.processing.SymbolProcessor
+import com.google.devtools.ksp.processing.SymbolProcessorEnvironment
import com.google.devtools.ksp.processing.SymbolProcessorProvider
import com.google.devtools.ksp.symbol.KSAnnotated
@@ -47,16 +48,11 @@
}
class Provider : SymbolProcessorProvider {
- override fun create(
- options: Map<String, String>,
- kotlinVersion: KotlinVersion,
- codeGenerator: CodeGenerator,
- logger: KSPLogger
- ): SymbolProcessor {
+ override fun create(environment: SymbolProcessorEnvironment): SymbolProcessor {
return RoomKspProcessor(
- options = options,
- codeGenerator = codeGenerator,
- logger = logger
+ options = environment.options,
+ codeGenerator = environment.codeGenerator,
+ logger = environment.logger
)
}
}