Make sure boxed primitives from java map to their boxed types
This CL fixes a bug where kspEnv.getType would return primitives for boxed
java primitives. (e.g. getType(java.lang.Long) would return long).
This CL fixes that and also adds tests to ensure some best effort conversion
for kotlin.Int as well (that is, non-null defaults to int and nullable defaults
to java.lang.Integer)
Bug: 160322705
Test: XProcessingEnvTest, KspProcessingEnvTest
Change-Id: I27349d47bc09f53fa367acf981dd0b5f9fdafe0e
diff --git a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspTypeMapper.kt b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspTypeMapper.kt
index c4086a8..734f3b1 100644
--- a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspTypeMapper.kt
+++ b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspTypeMapper.kt
@@ -46,6 +46,10 @@
"kotlin.Double" to TypeName.DOUBLE,
"kotlin.Boolean" to TypeName.BOOLEAN
)
+ private val javaPrimitiveQNames = kotlinTypeToJavaPrimitiveMapping
+ .values.mapTo(mutableSetOf()) {
+ it.toString()
+ }
init {
// https://kotlinlang.org/docs/reference/java-interop.html#mapped-types
@@ -84,7 +88,5 @@
fun getPrimitiveJavaTypeName(kotlinType: String) = kotlinTypeToJavaPrimitiveMapping[kotlinType]
- fun isJavaPrimitiveType(qName: String) = mapping[qName]?.let {
- kotlinTypeToJavaPrimitiveMapping[it]
- } != null
+ fun isJavaPrimitiveType(qName: String) = javaPrimitiveQNames.contains(qName)
}
diff --git a/room/compiler-processing/src/test/java/androidx/room/compiler/processing/XProcessingEnvTest.kt b/room/compiler-processing/src/test/java/androidx/room/compiler/processing/XProcessingEnvTest.kt
index 12f726f..4ae8c01 100644
--- a/room/compiler-processing/src/test/java/androidx/room/compiler/processing/XProcessingEnvTest.kt
+++ b/room/compiler-processing/src/test/java/androidx/room/compiler/processing/XProcessingEnvTest.kt
@@ -141,13 +141,12 @@
runProcessorTestIncludingKsp(
listOf(source)
) { invocation ->
- PRIMITIVE_TYPES.forEach {
- val targetType = invocation.processingEnv.findType(it.key)
- assertThat(targetType?.typeName).isEqualTo(it.value)
- if (!invocation.isKsp) {
- // TODO re-enable once we move typenames to the java realm
- assertThat(targetType?.boxed()?.typeName).isEqualTo(it.value.box())
- }
+ PRIMITIVE_TYPES.flatMap {
+ listOf(it, it.box())
+ }.forEach {
+ val targetType = invocation.processingEnv.findType(it.toString())
+ assertThat(targetType?.typeName).isEqualTo(it)
+ assertThat(targetType?.boxed()?.typeName).isEqualTo(it.box())
}
}
}
@@ -236,15 +235,15 @@
}
companion object {
- val PRIMITIVE_TYPES = mapOf(
- TypeName.BOOLEAN.toString() to TypeName.BOOLEAN,
- TypeName.BYTE.toString() to TypeName.BYTE,
- TypeName.SHORT.toString() to TypeName.SHORT,
- TypeName.INT.toString() to TypeName.INT,
- TypeName.LONG.toString() to TypeName.LONG,
- TypeName.CHAR.toString() to TypeName.CHAR,
- TypeName.FLOAT.toString() to TypeName.FLOAT,
- TypeName.DOUBLE.toString() to TypeName.DOUBLE
+ val PRIMITIVE_TYPES = listOf(
+ TypeName.BOOLEAN,
+ TypeName.BYTE,
+ TypeName.SHORT,
+ TypeName.INT,
+ TypeName.LONG,
+ TypeName.CHAR,
+ TypeName.FLOAT,
+ TypeName.DOUBLE,
)
}
}
diff --git a/room/compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KspProcessingEnvTest.kt b/room/compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KspProcessingEnvTest.kt
new file mode 100644
index 0000000..e0cd5e3
--- /dev/null
+++ b/room/compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KspProcessingEnvTest.kt
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2020 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.XNullability
+import androidx.room.compiler.processing.util.runKspTest
+import com.google.common.truth.Truth.assertThat
+import com.squareup.javapoet.TypeName
+import org.junit.Test
+
+class KspProcessingEnvTest {
+ @Test
+ fun wrapPrimitives() {
+ // make sure nullable primitives turns into the boxed version of it.
+ // and non-null turns into the primitive version of it.
+ runKspTest(sources = emptyList()) { invocation ->
+ val intType = invocation.kspResolver.builtIns.intType
+ val kspProcessingEnv = invocation.processingEnv as KspProcessingEnv
+ kspProcessingEnv.wrap(
+ ksType = intType,
+ allowPrimitives = true
+ ).let {
+ assertThat(it.nullability).isEqualTo(
+ XNullability.NONNULL
+ )
+ assertThat(it.typeName).isEqualTo(TypeName.INT)
+ }
+ kspProcessingEnv.wrap(
+ ksType = intType,
+ allowPrimitives = false
+ ).let {
+ assertThat(it.nullability).isEqualTo(
+ XNullability.NONNULL
+ )
+ assertThat(it.typeName).isEqualTo(TypeName.INT.box())
+ }
+ kspProcessingEnv.wrap(
+ ksType = intType.makeNullable(),
+ allowPrimitives = true
+ ).let {
+ assertThat(it.nullability).isEqualTo(
+ XNullability.NULLABLE
+ )
+ assertThat(it.typeName).isEqualTo(TypeName.INT.box())
+ }
+ }
+ }
+}