Introduce KspPrimitive Type

This CL introduces a new KspPrimitiveType : KspType which is used
to represent java primitives in KSP as primitives do not exist in
Kotlin.

Unfortunately, we cannot decide whether a kotlin type will be a
primitive or not just by looking at the type itself. For instance,
in most cases, a `kotlin.Int!!` is a java `int` but it might also
be mapped to `java.lang.Integer` if the type was resolved from a
type parameter (e.g. List<kotlin.Int>.get returns a boxed Integer).

To support this, I've removed the `wrap(KSType)` method from
KspProcessingEnv and replaced it with a wrap method that also
expects the KSTypeReference. KspProcessingEnv uses that type
reference to see if the references was resolved from a type
parameter. For cases where we always want the boxed type (e.g.
type of a TypeElement, there is a wrapDeclared method).

This is still not fully complete as it will miss overrides but
for overrides, kotlin generates two methods (see aosp/1458703).
I'll tackle that when we can run integration tests.

This CL makes TypeNames a bit inconsistent as the primitive types
are the only TypeNames in java. I'll followup with another CL
where
* TypeNames are always generated in java
* Ksp processing always uses kotlin types (e.g. java.util.List will
be mapped to kotlin.collections.MutableList).

After that CL, consistency will come back and then we'll start
running integration tests.

Bug: 160322705
Test: Existing tests + XProcessingEnvTest#getPrimitives
Change-Id: I271171cf7b35cd8f4249350fbdfadf81f55e6a8a
diff --git a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/JavaPoetExt.kt b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/JavaPoetExt.kt
index 8b3859b..268a5f7 100644
--- a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/JavaPoetExt.kt
+++ b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/JavaPoetExt.kt
@@ -63,6 +63,28 @@
 }
 
 /**
+ * Returns the unboxed TypeName for this if it can be unboxed, otherwise, returns this.
+ */
+internal fun TypeName.tryUnbox(): TypeName {
+    return if (isBoxedPrimitive) {
+        unbox()
+    } else {
+        this
+    }
+}
+
+/**
+ * Returns the boxed TypeName for this if it can be unboxed, otherwise, returns this.
+ */
+internal fun TypeName.tryBox(): TypeName {
+    return try {
+        box()
+    } catch (err: AssertionError) {
+        this
+    }
+}
+
+/**
  * Helper class to create overrides for XExecutableElements with final parameters and correct
  * parameter names read from Kotlin Metadata.
  */
diff --git a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KSTypeExt.kt b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KSTypeExt.kt
index fe0ba08..7a39e00 100644
--- a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KSTypeExt.kt
+++ b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KSTypeExt.kt
@@ -118,4 +118,8 @@
     return checkNotNull(type?.resolve()) {
         "KSTypeArgument.type should not have been null, please file a bug. $this"
     }
+}
+
+internal fun KSTypeReference.isTypeParameterReference(): Boolean {
+    return this.resolve().declaration is KSTypeParameter
 }
\ No newline at end of file
diff --git a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspAnnotationBox.kt b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspAnnotationBox.kt
index 6df5430..4e308fb 100644
--- a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspAnnotationBox.kt
+++ b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspAnnotationBox.kt
@@ -30,12 +30,12 @@
 ) : XAnnotationBox<T> {
     override fun getAsType(methodName: String): XType? {
         val value = getFieldValue<KSType>(methodName)
-        return value?.let(env::wrap)
+        return value?.let(env::wrapDeclared)
     }
 
     override fun getAsTypeList(methodName: String): List<XType> {
         val values = getFieldValue<List<KSType>>(methodName) ?: return emptyList()
-        return values.map(env::wrap)
+        return values.map(env::wrapDeclared)
     }
 
     override fun <R : Annotation> getAsAnnotationBox(methodName: String): XAnnotationBox<R> {
diff --git a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspDeclaredType.kt b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspDeclaredType.kt
index 8b630ed..85752cd 100644
--- a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspDeclaredType.kt
+++ b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspDeclaredType.kt
@@ -18,8 +18,8 @@
 
 import androidx.room.compiler.processing.XDeclaredType
 import androidx.room.compiler.processing.XType
-import com.squareup.javapoet.TypeName
 import com.google.devtools.ksp.symbol.KSType
+import com.squareup.javapoet.TypeName
 
 internal open class KspDeclaredType(
     env: KspProcessingEnv,
diff --git a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspExecutableParameterElement.kt b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspExecutableParameterElement.kt
index 7e2d647..728033e 100644
--- a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspExecutableParameterElement.kt
+++ b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspExecutableParameterElement.kt
@@ -43,7 +43,12 @@
             resolver = env.resolver,
             functionDeclaration = method.declaration,
             ksType = method.containing.declaration.asStarProjectedType()
-        ).let(env::wrap)
+        ).let {
+            env.wrap(
+                originatingReference = parameter.type!!, // as member of doesn't allow nulls
+                ksType = it
+            )
+        }
     }
 
     override fun asMemberOf(other: XDeclaredType): XType {
@@ -55,7 +60,12 @@
             resolver = env.resolver,
             functionDeclaration = method.declaration,
             ksType = other.ksType
-        ).let(env::wrap)
+        ).let {
+            env.wrap(
+                originatingReference = parameter.type!!, // as member of doesn't allow nulls
+                ksType = it
+            )
+        }
     }
 
     override fun kindName(): String {
diff --git a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspFieldElement.kt b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspFieldElement.kt
index 5bdbddd..e997671 100644
--- a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspFieldElement.kt
+++ b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspFieldElement.kt
@@ -47,7 +47,10 @@
     }
 
     override val type: XType by lazy {
-        env.wrap(declaration.typeAsMemberOf(env.resolver, containing.type.ksType))
+        env.wrap(
+            originatingReference = declaration.type,
+            ksType = declaration.typeAsMemberOf(env.resolver, containing.type.ksType)
+        )
     }
 
     override fun asMemberOf(other: XDeclaredType): XType {
@@ -56,7 +59,10 @@
         }
         check(other is KspType)
         val asMember = declaration.typeAsMemberOf(env.resolver, other.ksType)
-        return env.wrap(asMember)
+        return env.wrap(
+            originatingReference = declaration.type,
+            ksType = asMember
+        )
     }
 
     fun copyTo(newContaining: KspTypeElement) = KspFieldElement(
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 74c2e38..ab01a0b 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
@@ -114,7 +114,7 @@
         override fun isSuspendFunction() = true
 
         override val returnType: XType by lazy {
-            env.wrap(env.resolver.builtIns.anyType.makeNullable())
+            env.wrapDeclared(env.resolver.builtIns.anyType.makeNullable())
         }
 
         override val parameters: List<XExecutableParameterElement>
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 cca29f31..218643a 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
@@ -52,7 +52,8 @@
     ) : KspMethodType(env, origin, containing) {
         override val returnType: XType by lazy {
             env.wrap(
-                origin.declaration.returnTypeAsMemberOf(
+                originatingReference = origin.declaration.returnType!!,
+                ksType = origin.declaration.returnTypeAsMemberOf(
                     resolver = env.resolver,
                     ksType = containing.ksType
                 )
@@ -70,8 +71,9 @@
             get() = origin.returnType
 
         override fun getSuspendFunctionReturnType(): XType {
-            return env.wrap(
-                origin.declaration.returnTypeAsMemberOf(
+            // suspend functions work w/ continuation so it is always declared
+            return env.wrapDeclared(
+                ksType = origin.declaration.returnTypeAsMemberOf(
                     resolver = env.resolver,
                     ksType = containing.ksType
                 )
diff --git a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspPrimitiveType.kt b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspPrimitiveType.kt
new file mode 100644
index 0000000..21af989
--- /dev/null
+++ b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspPrimitiveType.kt
@@ -0,0 +1,45 @@
+/*
+ * 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 com.google.devtools.ksp.symbol.KSType
+import com.squareup.javapoet.TypeName
+
+/**
+ * This tries to mimic primitive types in Kotlin.
+ *
+ * Primitiveness of a type cannot always be driven from itself (e.g. its nullability).
+ * For instance, a kotlin.Int might be non-null but still be non primitive if it is derived from a
+ * generic type argument or is part of type parameters.
+ */
+internal class KspPrimitiveType(
+    env: KspProcessingEnv,
+    ksType: KSType
+) : KspType(env, ksType) {
+    override val typeName: TypeName by lazy {
+        // TODO once we generate type names in java realm, this custom conversion won't be necessary
+        // for now, temporarily, we only do conversion here in place
+        return@lazy checkNotNull(
+            KspTypeMapper.getPrimitiveJavaTypeName(
+                ksType.declaration.qualifiedName!!.asString()
+            )
+        ) {
+            "Internal error. Should've found a java primitive for " +
+                "${ksType.declaration.qualifiedName}"
+        }
+    }
+}
diff --git a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspProcessingEnv.kt b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspProcessingEnv.kt
index 41d2747..c752c97 100644
--- a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspProcessingEnv.kt
+++ b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspProcessingEnv.kt
@@ -24,6 +24,7 @@
 import androidx.room.compiler.processing.XType
 import androidx.room.compiler.processing.XTypeElement
 import androidx.room.compiler.processing.javac.XTypeElementStore
+import com.google.devtools.ksp.getClassDeclarationByName
 import com.google.devtools.ksp.processing.CodeGenerator
 import com.google.devtools.ksp.processing.KSPLogger
 import com.google.devtools.ksp.processing.Resolver
@@ -32,6 +33,7 @@
 import com.google.devtools.ksp.symbol.KSTypeArgument
 import com.google.devtools.ksp.symbol.KSTypeParameter
 import com.google.devtools.ksp.symbol.KSTypeReference
+import com.google.devtools.ksp.symbol.Nullability
 import com.google.devtools.ksp.symbol.Variance
 
 internal class KspProcessingEnv(
@@ -44,7 +46,7 @@
     private val typeElementStore =
         XTypeElementStore { qName ->
             resolver.getClassDeclarationByName(
-                resolver.getKSNameFromString(qName)
+                KspTypeMapper.swapWithKotlinType(qName)
             )?.let {
                 KspTypeElement(
                     env = this,
@@ -64,8 +66,12 @@
     }
 
     override fun findType(qName: String): XType? {
-        return resolver.findClass(qName)?.let {
-            wrap(it.asStarProjectedType())
+        val kotlinTypeName = KspTypeMapper.swapWithKotlinType(qName)
+        return resolver.findClass(kotlinTypeName)?.let {
+            wrap(
+                allowPrimitives = KspTypeMapper.isJavaPrimitiveType(qName),
+                ksType = it.asStarProjectedType()
+            )
         }
     }
 
@@ -90,7 +96,7 @@
                 variance = Variance.INVARIANT
             )
         }
-        return wrap(
+        return wrapDeclared(
             type.declaration.asType(typeArguments)
         )
     }
@@ -112,21 +118,44 @@
         )
     }
 
-    fun wrap(ksType: KSType): KspDeclaredType {
-        return if (ksType.declaration.qualifiedName?.asString() == KOTLIN_ARRAY_Q_NAME) {
-            KspArrayType(
-                env = this,
-                ksType = ksType
-            )
-        } else {
-            KspDeclaredType(this, ksType)
-        }
+    /**
+     * Wraps the given `ksType` as a [KspDeclaredType].
+     * For the edge cases where `ksType` potentially represents a java primitive, it is always
+     * boxed.
+     */
+    fun wrapDeclared(ksType: KSType): KspDeclaredType {
+        return wrap(
+            ksType = ksType,
+            allowPrimitives = false
+        ) as KspDeclaredType
     }
 
-    fun wrap(ksTypeReference: KSTypeReference): KspDeclaredType {
-        return wrap(ksTypeReference.resolve())
+    /**
+     * Wraps the given `ksType`.
+     *
+     * The [originatingReference] is used to calculate whether the given [ksType] can be a
+     * primitive or not.
+     */
+    fun wrap(
+        originatingReference: KSTypeReference,
+        ksType: KSType
+    ): KspType {
+        return wrap(
+            ksType = ksType,
+            allowPrimitives = !originatingReference.isTypeParameterReference()
+        )
     }
 
+    /**
+     * Wraps the given [typeReference] in to a [KspType].
+     */
+    fun wrap(
+        typeReference: KSTypeReference
+    ) = wrap(
+        originatingReference = typeReference,
+        ksType = typeReference.resolve()
+    )
+
     fun wrap(ksTypeParam: KSTypeParameter, ksTypeArgument: KSTypeArgument): KspTypeArgumentType {
         return KspTypeArgumentType(
             env = this,
@@ -135,6 +164,33 @@
         )
     }
 
+    /**
+     * Wraps the given KSType into a KspType.
+     *
+     * Certain Kotlin types might be primitives in Java but such information cannot be derived
+     * just by looking at the type itself.
+     * Instead, it is passed in an argument to this function and public wrap functions make that
+     * decision.
+     */
+    private fun wrap(ksType: KSType, allowPrimitives: Boolean): KspType {
+        val qName = ksType.declaration.qualifiedName?.asString()
+        if (allowPrimitives && qName != null && ksType.nullability == Nullability.NOT_NULL) {
+            // check for primitives
+            val javaPrimitive = KspTypeMapper.getPrimitiveJavaTypeName(qName)
+            if (javaPrimitive != null) {
+                return KspPrimitiveType(this, ksType)
+            }
+        }
+        return if (qName == KOTLIN_ARRAY_Q_NAME) {
+            KspArrayType(
+                env = this,
+                ksType = ksType
+            )
+        } else {
+            KspDeclaredType(this, ksType)
+        }
+    }
+
     fun wrapClassDeclaration(declaration: KSClassDeclaration): KspTypeElement {
         return KspTypeElement(
             env = this,
diff --git a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspType.kt b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspType.kt
index fecc613..3b825dd 100644
--- a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspType.kt
+++ b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspType.kt
@@ -118,7 +118,17 @@
 
     override fun isTypeOf(other: KClass<*>): Boolean {
         // closest to what MoreTypes#isTypeOf does.
-        return rawType.typeName.toString() == other.qualifiedName
+        // TODO once we move TypeNames to java realm, we will be able to check just using that
+        //  (+ boxing). Fow now, this code stays flexible and checks for all variations as
+        //  only primitives use java types now.
+        val rawTypeName = rawType.typeName
+        // other might be something like Kotlin.Int which would map to primitive int (when
+        // invoked with .java) hence we need to check the qualified name for both.
+        // similar case for lists.
+        val javaQName = other.java.canonicalName
+        val kotlinQName = other.qualifiedName
+        val myQName = rawTypeName.toString()
+        return myQName == javaQName || myQName == kotlinQName
     }
 
     override fun isSameType(other: XType): Boolean {
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 8730aa1..c3bfde7 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
@@ -26,7 +26,6 @@
 import androidx.room.compiler.processing.ksp.KspAnnotated.UseSiteFilter.Companion.NO_USE_SITE
 import androidx.room.compiler.processing.ksp.synthetic.KspSyntheticConstructorForJava
 import androidx.room.compiler.processing.ksp.synthetic.KspSyntheticPropertyMethodElement
-import com.squareup.javapoet.ClassName
 import com.google.devtools.ksp.getAllSuperTypes
 import com.google.devtools.ksp.getDeclaredFunctions
 import com.google.devtools.ksp.getDeclaredProperties
@@ -37,6 +36,7 @@
 import com.google.devtools.ksp.symbol.KSPropertyDeclaration
 import com.google.devtools.ksp.symbol.Modifier
 import com.google.devtools.ksp.symbol.Origin
+import com.squareup.javapoet.ClassName
 
 internal class KspTypeElement(
     env: KspProcessingEnv,
@@ -72,7 +72,7 @@
     }
 
     override val type: KspDeclaredType by lazy {
-        env.wrap(declaration.asStarProjectedType())
+        env.wrapDeclared(declaration.asStarProjectedType())
     }
 
     override val superType: XType? by lazy {
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
new file mode 100644
index 0000000..2ffa3e5
--- /dev/null
+++ b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspTypeMapper.kt
@@ -0,0 +1,65 @@
+/*
+ * 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 com.squareup.javapoet.TypeName
+
+/**
+ * Maps java specific types to their kotlin counterparts.
+ * see: https://github.com/google/ksp/issues/126
+ * see: https://github.com/google/ksp/issues/125
+ *
+ * `Resolver.getClassDeclarationByName` returns the java representation of a class even when a
+ * kotlin version of the same class exists. e.g. It returns a KSClassDeclaration representing
+ * `java.lang.String` if queried with `java.lang.String`. Even though this makes sense by itself,
+ * it is inconsistent with the kotlin compiler which will resolve all instances of
+ * `java.lang.String` to `kotlin.String` (even if it is in Java source code).
+ *
+ * Until KSP provides compiler consistent behavior, this helper utility does the mapping for us.
+ *
+ * This list is built from https://kotlinlang.org/docs/reference/java-interop.html#mapped-types.
+ * Hopefully, it will be temporary until KSP provides a utility to do the same conversion.
+ */
+object KspTypeMapper {
+    private val mapping = mutableMapOf<String, String>()
+    private val kotlinTypeToJavaPrimitiveMapping = mapOf(
+        "kotlin.Byte" to TypeName.BYTE,
+        "kotlin.Short" to TypeName.SHORT,
+        "kotlin.Int" to TypeName.INT,
+        "kotlin.Long" to TypeName.LONG,
+        "kotlin.Char" to TypeName.CHAR,
+        "kotlin.Float" to TypeName.FLOAT,
+        "kotlin.Double" to TypeName.DOUBLE,
+        "kotlin.Boolean" to TypeName.BOOLEAN
+    )
+
+    init {
+        // https://kotlinlang.org/docs/reference/java-interop.html#mapped-types
+        kotlinTypeToJavaPrimitiveMapping.forEach {
+            mapping[it.value.toString()] = it.key
+        }
+        // TODO Add non primitives after TypeNames move to the java type realm.
+    }
+
+    fun swapWithKotlinType(javaType: String): String = mapping[javaType] ?: javaType
+
+    fun getPrimitiveJavaTypeName(kotlinType: String) = kotlinTypeToJavaPrimitiveMapping[kotlinType]
+
+    fun isJavaPrimitiveType(qName: String) = mapping[qName]?.let {
+        kotlinTypeToJavaPrimitiveMapping[it]
+    } != null
+}
diff --git a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/synthetic/KspSyntheticContinuationParameterElement.kt b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/synthetic/KspSyntheticContinuationParameterElement.kt
index 1b5f8f4..42deaa39 100644
--- a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/synthetic/KspSyntheticContinuationParameterElement.kt
+++ b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/synthetic/KspSyntheticContinuationParameterElement.kt
@@ -65,7 +65,7 @@
                 )
             )
         )
-        env.wrap(contType)
+        env.wrapDeclared(contType)
     }
 
     override fun asMemberOf(other: XDeclaredType): XType {
@@ -83,7 +83,7 @@
             Variance.CONTRAVARIANT
         )
         val contType = continuation.asType(listOf(returnTypeAsTypeArgument))
-        return env.wrap(contType)
+        return env.wrapDeclared(contType)
     }
 
     override fun kindName(): String {
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 7b15858..dd1b778 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
@@ -174,7 +174,7 @@
         }
 
         override val returnType: XType by lazy {
-            env.wrap(
+            env.wrapDeclared(
                 env.resolver.builtIns.unitType
             )
         }
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 92d3afe..0e88d66 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
@@ -25,6 +25,7 @@
 import com.google.common.truth.Truth
 import com.google.common.truth.Truth.assertThat
 import com.squareup.javapoet.ParameterizedTypeName
+import com.squareup.javapoet.TypeName
 import com.squareup.javapoet.WildcardTypeName
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -202,7 +203,7 @@
                     invocation.types.string
                 )
                 assertThat(method.parameters[1].type.typeName).isEqualTo(
-                    invocation.types.int
+                    TypeName.INT
                 )
                 assertThat(method.isSuspendFunction()).isTrue()
                 assertThat(method.returnType.typeName).isEqualTo(invocation.types.objectOrAny)
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 2ea0df4..a5a7bc6 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
@@ -139,13 +139,16 @@
             }
             """.trimIndent()
         )
-        runProcessorTest(
+        runProcessorTestIncludingKsp(
             listOf(source)
         ) { invocation ->
             PRIMITIVE_TYPES.forEach {
                 val targetType = invocation.processingEnv.findType(it.key)
                 assertThat(targetType?.typeName).isEqualTo(it.value)
-                assertThat(targetType?.boxed()?.typeName).isEqualTo(it.value.box())
+                if (!invocation.isKsp) {
+                    // TODO re-enable once we move typenames to the java realm
+                    assertThat(targetType?.boxed()?.typeName).isEqualTo(it.value.box())
+                }
             }
         }
     }
diff --git a/room/compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KspTypeTest.kt b/room/compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KspTypeTest.kt
index 3944482..5b6e65f 100644
--- a/room/compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KspTypeTest.kt
+++ b/room/compiler-processing/src/test/java/androidx/room/compiler/processing/ksp/KspTypeTest.kt
@@ -27,7 +27,7 @@
 import com.google.devtools.ksp.getClassDeclarationByName
 import com.google.devtools.ksp.getDeclaredFunctions
 import com.google.devtools.ksp.symbol.KSPropertyDeclaration
-import com.google.devtools.ksp.symbol.KSTypeReference
+import com.squareup.javapoet.TypeName
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.junit.runners.JUnit4
@@ -88,14 +88,14 @@
             listOf(src),
             succeed = false
         ) { invocation ->
-            invocation.requirePropertyType("errorType").let { type ->
+            invocation.requireDeclaredPropertyType("errorType").let { type ->
                 assertThat(type.isError()).isTrue()
                 assertThat(type.typeArguments).isEmpty()
                 assertThat(type.typeName).isEqualTo(ERROR_TYPE_NAME)
                 assertThat(type.asTypeElement().className).isEqualTo(ERROR_TYPE_NAME)
             }
 
-            invocation.requirePropertyType("listOfErrorType").let { type ->
+            invocation.requireDeclaredPropertyType("listOfErrorType").let { type ->
                 assertThat(type.isError()).isFalse()
                 assertThat(type.typeArguments).hasSize(1)
                 type.typeArguments.single().let { typeArg ->
@@ -120,7 +120,7 @@
             listOf(src),
             succeed = true
         ) { invocation ->
-            invocation.requirePropertyType("listOfNullableStrings").let { type ->
+            invocation.requireDeclaredPropertyType("listOfNullableStrings").let { type ->
                 assertThat(type.nullability).isEqualTo(NONNULL)
                 assertThat(type.typeArguments).hasSize(1)
                 assertThat(type.asTypeElement().className).isEqualTo(
@@ -136,7 +136,7 @@
                 }
             }
 
-            invocation.requirePropertyType("listOfInts").let { type ->
+            invocation.requireDeclaredPropertyType("listOfInts").let { type ->
                 assertThat(type.nullability).isEqualTo(NONNULL)
                 assertThat(type.typeArguments).hasSize(1)
                 type.typeArguments.single().let { typeArg ->
@@ -172,13 +172,17 @@
             listOf(src),
             succeed = true
         ) { invocation ->
-            val nullableStringList = invocation.requirePropertyType("listOfNullableStrings")
-            val nonNullStringList = invocation.requirePropertyType("listOfNonNullStrings")
+            val nullableStringList = invocation
+                .requireDeclaredPropertyType("listOfNullableStrings")
+            val nonNullStringList = invocation
+                .requireDeclaredPropertyType("listOfNonNullStrings")
             assertThat(nullableStringList).isNotEqualTo(nonNullStringList)
             assertThat(nonNullStringList).isNotEqualTo(nullableStringList)
 
-            val nullableStringList_2 = invocation.requirePropertyType("listOfNullableStrings_2")
-            val nonNullStringList_2 = invocation.requirePropertyType("listOfNonNullStrings_2")
+            val nullableStringList_2 = invocation
+                .requireDeclaredPropertyType("listOfNullableStrings_2")
+            val nonNullStringList_2 = invocation
+                .requireDeclaredPropertyType("listOfNonNullStrings_2")
             assertThat(nullableStringList).isEqualTo(nullableStringList_2)
             assertThat(nonNullStringList).isEqualTo(nonNullStringList_2)
 
@@ -216,21 +220,21 @@
             succeed = true
         ) { invocation ->
             invocation.requirePropertyType("simple").let {
-                assertThat(it.rawType.typeName).isEqualTo(ClassName.get("kotlin", "Int"))
+                assertThat(it.rawType.typeName).isEqualTo(TypeName.INT)
             }
-            invocation.requirePropertyType("list").let { list ->
+            invocation.requireDeclaredPropertyType("list").let { list ->
                 assertThat(list.rawType).isNotEqualTo(list)
                 assertThat(list.typeArguments).isNotEmpty()
                 assertThat(list.rawType.typeName)
                     .isEqualTo(ClassName.get("kotlin.collections", "List"))
             }
-            invocation.requirePropertyType("map").let { map ->
+            invocation.requireDeclaredPropertyType("map").let { map ->
                 assertThat(map.rawType).isNotEqualTo(map)
                 assertThat(map.typeArguments).hasSize(2)
                 assertThat(map.rawType.typeName)
                     .isEqualTo(ClassName.get("kotlin.collections", "Map"))
             }
-            invocation.requirePropertyType("listOfMaps").let { listOfMaps ->
+            invocation.requireDeclaredPropertyType("listOfMaps").let { listOfMaps ->
                 assertThat(listOfMaps.rawType).isNotEqualTo(listOfMaps)
                 assertThat(listOfMaps.typeArguments).hasSize(1)
             }
@@ -450,7 +454,7 @@
                     .single()
                     .type
                     .let {
-                        invocation.wrap(typeRef = it!!)
+                        invocation.processingEnv.wrapDeclared(it!!.resolve())
                     }
             }
             assertThat(typeArgs["Bar"]!!.typeName)
@@ -486,7 +490,9 @@
                 ?.first {
                     it.simpleName.asString() == "wildcardMethod"
                 } ?: throw AssertionError("cannot find test method")
-            val paramType = invocation.wrap(method.parameters.first().type!!)
+            val paramType = invocation.processingEnv.wrapDeclared(
+                method.parameters.first().type!!.resolve()
+            )
             val arg1 = paramType.typeArguments.single()
             assertThat(arg1.typeName)
                 .isEqualTo(
@@ -498,17 +504,22 @@
         }
     }
 
-    private fun TestInvocation.requirePropertyType(name: String): KspDeclaredType {
-        (processingEnv as KspProcessingEnv).resolver.getAllFiles().forEach { file ->
-            val prop = file.declarations.first {
-                it.simpleName.asString() == name
-            } as KSPropertyDeclaration
-            return wrap(prop.type)
-        }
-        throw IllegalStateException("cannot find any property with name $name")
+    private fun TestInvocation.requirePropertyType(name: String): KspType {
+        val prop = requireProperty(name)
+        return (processingEnv as KspProcessingEnv).wrap(prop.type)
     }
 
-    private fun TestInvocation.wrap(typeRef: KSTypeReference): KspDeclaredType {
-        return (processingEnv as KspProcessingEnv).wrap(typeRef)
+    private fun TestInvocation.requireDeclaredPropertyType(name: String): KspDeclaredType {
+        val prop = requireProperty(name)
+        return (processingEnv as KspProcessingEnv).wrapDeclared(prop.type.resolve())
+    }
+
+    private fun TestInvocation.requireProperty(name: String): KSPropertyDeclaration {
+        kspResolver.getAllFiles().forEach { file ->
+            return file.declarations.first {
+                it.simpleName.asString() == name
+            } as KSPropertyDeclaration
+        }
+        throw IllegalStateException("cannot find any property with name $name")
     }
 }
\ No newline at end of file
diff --git a/room/compiler-processing/src/test/java/androidx/room/compiler/processing/util/TestInvocation.kt b/room/compiler-processing/src/test/java/androidx/room/compiler/processing/util/TestInvocation.kt
index 5e0d428..ab5c68a 100644
--- a/room/compiler-processing/src/test/java/androidx/room/compiler/processing/util/TestInvocation.kt
+++ b/room/compiler-processing/src/test/java/androidx/room/compiler/processing/util/TestInvocation.kt
@@ -42,8 +42,6 @@
                 voidOrUnit = KotlinTypeNames.UNIT_CLASS_NAME,
                 objectOrAny = KotlinTypeNames.ANY_CLASS_NAME,
                 boxedInt = KotlinTypeNames.INT_CLASS_NAME,
-                int = KotlinTypeNames.INT_CLASS_NAME,
-                long = KotlinTypeNames.LONG_CLASS_NAME,
                 list = KotlinTypeNames.LIST_CLASS_NAME,
                 mutableSet = KotlinTypeNames.MUTABLESET_CLASS_NAME
             )
@@ -53,8 +51,6 @@
                 voidOrUnit = TypeName.VOID,
                 objectOrAny = TypeName.OBJECT,
                 boxedInt = TypeName.INT.box(),
-                int = TypeName.INT,
-                long = TypeName.LONG,
                 list = ClassName.get("java.util", "List"),
                 mutableSet = ClassName.get("java.util", "Set")
             )
@@ -70,8 +66,8 @@
         val voidOrUnit: TypeName,
         val objectOrAny: ClassName,
         val boxedInt: TypeName,
-        val int: TypeName,
-        val long: TypeName,
+        val int: TypeName = TypeName.INT,
+        val long: TypeName = TypeName.LONG,
         val list: ClassName,
         val mutableSet: TypeName
     )