Merge "Move XClassName into a separate file" into androidx-main
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/codegen/XClassName.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/codegen/XClassName.kt
new file mode 100644
index 0000000..914b990
--- /dev/null
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/codegen/XClassName.kt
@@ -0,0 +1,183 @@
+/*
+ * Copyright 2024 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.codegen
+
+import androidx.room.compiler.processing.XNullability
+import com.squareup.kotlinpoet.MUTABLE_COLLECTION
+import com.squareup.kotlinpoet.MUTABLE_ITERABLE
+import com.squareup.kotlinpoet.MUTABLE_LIST
+import com.squareup.kotlinpoet.MUTABLE_MAP
+import com.squareup.kotlinpoet.MUTABLE_MAP_ENTRY
+import com.squareup.kotlinpoet.MUTABLE_SET
+import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy
+import com.squareup.kotlinpoet.asClassName as asKClassName
+import com.squareup.kotlinpoet.javapoet.JClassName
+import com.squareup.kotlinpoet.javapoet.JParameterizedTypeName
+import com.squareup.kotlinpoet.javapoet.JTypeName
+import com.squareup.kotlinpoet.javapoet.KClassName
+import kotlin.reflect.KClass
+
+/**
+ * Represents a fully-qualified class name.
+ *
+ * It simply contains a [com.squareup.javapoet.ClassName] and a [com.squareup.kotlinpoet.ClassName].
+ *
+ * @see [androidx.room.compiler.processing.XTypeElement.asClassName]
+ */
+class XClassName
+internal constructor(
+ override val java: JClassName,
+ override val kotlin: KClassName,
+ nullability: XNullability
+) : XTypeName(java, kotlin, nullability) {
+
+ // TODO(b/248000692): Using the JClassName as source of truth. This is wrong since we need to
+ // handle Kotlin interop types for KotlinPoet, i.e. java.lang.String to kotlin.String.
+ // But a decision has to be made...
+ val packageName: String = java.packageName()
+ val simpleNames: List<String> = java.simpleNames()
+ val canonicalName: String = java.canonicalName()
+ val reflectionName: String = java.reflectionName()
+
+ /**
+ * Returns a parameterized type, applying the `typeArguments` to `this`.
+ *
+ * @see [XTypeName.rawTypeName]
+ */
+ fun parametrizedBy(
+ vararg typeArguments: XTypeName,
+ ): XTypeName {
+ return XTypeName(
+ java = JParameterizedTypeName.get(java, *typeArguments.map { it.java }.toTypedArray()),
+ kotlin =
+ if (
+ kotlin != UNAVAILABLE_KTYPE_NAME &&
+ typeArguments.none { it.kotlin == UNAVAILABLE_KTYPE_NAME }
+ ) {
+ kotlin.parameterizedBy(typeArguments.map { it.kotlin })
+ } else {
+ UNAVAILABLE_KTYPE_NAME
+ }
+ )
+ }
+
+ fun nestedClass(name: String) =
+ XClassName(
+ java = java.nestedClass(name),
+ kotlin = kotlin.nestedClass(name),
+ nullability = XNullability.NONNULL
+ )
+
+ override fun copy(nullable: Boolean): XClassName {
+ return XClassName(
+ java = java,
+ kotlin =
+ if (kotlin != UNAVAILABLE_KTYPE_NAME) {
+ kotlin.copy(nullable = nullable) as KClassName
+ } else {
+ UNAVAILABLE_KTYPE_NAME
+ },
+ nullability = if (nullable) XNullability.NULLABLE else XNullability.NONNULL
+ )
+ }
+
+ companion object {
+ // TODO(b/248633751): Handle interop types.
+ @JvmStatic
+ fun get(packageName: String, vararg names: String): XClassName {
+ return XClassName(
+ java = JClassName.get(packageName, names.first(), *names.drop(1).toTypedArray()),
+ kotlin = KClassName(packageName, *names),
+ nullability = XNullability.NONNULL
+ )
+ }
+ }
+}
+
+/**
+ * Creates a [XClassName] from the receiver [KClass]
+ *
+ * When the receiver [KClass] is a Kotlin interop primitive, such as [kotlin.Int] then the returned
+ * [XClassName] contains the boxed JavaPoet class name.
+ *
+ * When the receiver [KClass] is a Kotlin interop collection, such as [kotlin.collections.List] then
+ * the returned [XClassName] contains the corresponding JavaPoet class name. See:
+ * https://kotlinlang.org/docs/reference/java-interop.html#mapped-types.
+ *
+ * When the receiver [KClass] is a Kotlin mutable collection, such as
+ * [kotlin.collections.MutableList] then the non-mutable [XClassName] is returned due to the mutable
+ * interfaces only existing at compile-time, see: https://youtrack.jetbrains.com/issue/KT-11754.
+ *
+ * If the mutable [XClassName] is needed, use [asMutableClassName].
+ */
+fun KClass<*>.asClassName(): XClassName {
+ val jClassName =
+ if (this.java.isPrimitive) {
+ getBoxedJClassName(this.java)
+ } else {
+ JClassName.get(this.java)
+ }
+ val kClassName = this.asKClassName()
+ return XClassName(java = jClassName, kotlin = kClassName, nullability = XNullability.NONNULL)
+}
+
+/**
+ * Creates a mutable [XClassName] from the receiver [KClass]
+ *
+ * This is a workaround for: https://github.com/square/kotlinpoet/issues/279
+ * https://youtrack.jetbrains.com/issue/KT-11754
+ *
+ * When the receiver [KClass] is a Kotlin interop collection, such as [kotlin.collections.List] then
+ * the returned [XClassName] contains the corresponding JavaPoet class name. See:
+ * https://kotlinlang.org/docs/reference/java-interop.html#mapped-types.
+ *
+ * When the receiver [KClass] is a Kotlin mutable collection, such as
+ * [kotlin.collections.MutableList] then the returned [XClassName] contains the corresponding
+ * KotlinPoet class name.
+ *
+ * If an equivalent interop [XClassName] mapping for a Kotlin mutable Kotlin collection receiver
+ * [KClass] is not found, the method will error out.
+ */
+fun KClass<*>.asMutableClassName(): XClassName {
+ val java = JClassName.get(this.java)
+ val kotlin =
+ when (this) {
+ Iterable::class -> MUTABLE_ITERABLE
+ Collection::class -> MUTABLE_COLLECTION
+ List::class -> MUTABLE_LIST
+ Set::class -> MUTABLE_SET
+ Map::class -> MUTABLE_MAP
+ Map.Entry::class -> MUTABLE_MAP_ENTRY
+ else -> error("No equivalent mutable Kotlin interop found for `$this`.")
+ }
+ return XClassName(java, kotlin, XNullability.NONNULL)
+}
+
+private fun getBoxedJClassName(klass: Class<*>): JClassName =
+ when (klass) {
+ java.lang.Void.TYPE -> JTypeName.VOID.box()
+ java.lang.Boolean.TYPE -> JTypeName.BOOLEAN.box()
+ java.lang.Byte.TYPE -> JTypeName.BYTE.box()
+ java.lang.Short.TYPE -> JTypeName.SHORT.box()
+ java.lang.Integer.TYPE -> JTypeName.INT.box()
+ java.lang.Long.TYPE -> JTypeName.LONG.box()
+ java.lang.Character.TYPE -> JTypeName.CHAR.box()
+ java.lang.Float.TYPE -> JTypeName.FLOAT.box()
+ java.lang.Double.TYPE -> JTypeName.DOUBLE.box()
+ else -> error("Can't get JTypeName from java.lang.Class: $klass")
+ }
+ as JClassName
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/codegen/XTypeName.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/codegen/XTypeName.kt
index fd426fc..5680e41 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/codegen/XTypeName.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/codegen/XTypeName.kt
@@ -25,15 +25,8 @@
import com.squareup.kotlinpoet.FLOAT_ARRAY
import com.squareup.kotlinpoet.INT_ARRAY
import com.squareup.kotlinpoet.LONG_ARRAY
-import com.squareup.kotlinpoet.MUTABLE_COLLECTION
-import com.squareup.kotlinpoet.MUTABLE_ITERABLE
-import com.squareup.kotlinpoet.MUTABLE_LIST
-import com.squareup.kotlinpoet.MUTABLE_MAP
-import com.squareup.kotlinpoet.MUTABLE_MAP_ENTRY
-import com.squareup.kotlinpoet.MUTABLE_SET
import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy
import com.squareup.kotlinpoet.SHORT_ARRAY
-import com.squareup.kotlinpoet.asClassName as asKClassName
import com.squareup.kotlinpoet.asTypeName as asKTypeName
import com.squareup.kotlinpoet.javapoet.JClassName
import com.squareup.kotlinpoet.javapoet.JParameterizedTypeName
@@ -290,157 +283,6 @@
}
/**
- * Represents a fully-qualified class name.
- *
- * It simply contains a [com.squareup.javapoet.ClassName] and a [com.squareup.kotlinpoet.ClassName].
- *
- * @see [androidx.room.compiler.processing.XTypeElement.asClassName]
- */
-class XClassName
-internal constructor(
- override val java: JClassName,
- override val kotlin: KClassName,
- nullability: XNullability
-) : XTypeName(java, kotlin, nullability) {
-
- // TODO(b/248000692): Using the JClassName as source of truth. This is wrong since we need to
- // handle Kotlin interop types for KotlinPoet, i.e. java.lang.String to kotlin.String.
- // But a decision has to be made...
- val packageName: String = java.packageName()
- val simpleNames: List<String> = java.simpleNames()
- val canonicalName: String = java.canonicalName()
- val reflectionName: String = java.reflectionName()
-
- /**
- * Returns a parameterized type, applying the `typeArguments` to `this`.
- *
- * @see [XTypeName.rawTypeName]
- */
- fun parametrizedBy(
- vararg typeArguments: XTypeName,
- ): XTypeName {
- return XTypeName(
- java = JParameterizedTypeName.get(java, *typeArguments.map { it.java }.toTypedArray()),
- kotlin =
- if (
- kotlin != UNAVAILABLE_KTYPE_NAME &&
- typeArguments.none { it.kotlin == UNAVAILABLE_KTYPE_NAME }
- ) {
- kotlin.parameterizedBy(typeArguments.map { it.kotlin })
- } else {
- UNAVAILABLE_KTYPE_NAME
- }
- )
- }
-
- fun nestedClass(name: String) =
- XClassName(
- java = java.nestedClass(name),
- kotlin = kotlin.nestedClass(name),
- nullability = XNullability.NONNULL
- )
-
- override fun copy(nullable: Boolean): XClassName {
- return XClassName(
- java = java,
- kotlin =
- if (kotlin != UNAVAILABLE_KTYPE_NAME) {
- kotlin.copy(nullable = nullable) as KClassName
- } else {
- UNAVAILABLE_KTYPE_NAME
- },
- nullability = if (nullable) XNullability.NULLABLE else XNullability.NONNULL
- )
- }
-
- companion object {
- // TODO(b/248633751): Handle interop types.
- @JvmStatic
- fun get(packageName: String, vararg names: String): XClassName {
- return XClassName(
- java = JClassName.get(packageName, names.first(), *names.drop(1).toTypedArray()),
- kotlin = KClassName(packageName, *names),
- nullability = XNullability.NONNULL
- )
- }
- }
-}
-
-/**
- * Creates a [XClassName] from the receiver [KClass]
- *
- * When the receiver [KClass] is a Kotlin interop primitive, such as [kotlin.Int] then the returned
- * [XClassName] contains the boxed JavaPoet class name.
- *
- * When the receiver [KClass] is a Kotlin interop collection, such as [kotlin.collections.List] then
- * the returned [XClassName] contains the corresponding JavaPoet class name. See:
- * https://kotlinlang.org/docs/reference/java-interop.html#mapped-types.
- *
- * When the receiver [KClass] is a Kotlin mutable collection, such as
- * [kotlin.collections.MutableList] then the non-mutable [XClassName] is returned due to the mutable
- * interfaces only existing at compile-time, see: https://youtrack.jetbrains.com/issue/KT-11754.
- *
- * If the mutable [XClassName] is needed, use [asMutableClassName].
- */
-fun KClass<*>.asClassName(): XClassName {
- val jClassName =
- if (this.java.isPrimitive) {
- getBoxedJClassName(this.java)
- } else {
- JClassName.get(this.java)
- }
- val kClassName = this.asKClassName()
- return XClassName(java = jClassName, kotlin = kClassName, nullability = XNullability.NONNULL)
-}
-
-/**
- * Creates a mutable [XClassName] from the receiver [KClass]
- *
- * This is a workaround for: https://github.com/square/kotlinpoet/issues/279
- * https://youtrack.jetbrains.com/issue/KT-11754
- *
- * When the receiver [KClass] is a Kotlin interop collection, such as [kotlin.collections.List] then
- * the returned [XClassName] contains the corresponding JavaPoet class name. See:
- * https://kotlinlang.org/docs/reference/java-interop.html#mapped-types.
- *
- * When the receiver [KClass] is a Kotlin mutable collection, such as
- * [kotlin.collections.MutableList] then the returned [XClassName] contains the corresponding
- * KotlinPoet class name.
- *
- * If an equivalent interop [XClassName] mapping for a Kotlin mutable Kotlin collection receiver
- * [KClass] is not found, the method will error out.
- */
-fun KClass<*>.asMutableClassName(): XClassName {
- val java = JClassName.get(this.java)
- val kotlin =
- when (this) {
- Iterable::class -> MUTABLE_ITERABLE
- Collection::class -> MUTABLE_COLLECTION
- List::class -> MUTABLE_LIST
- Set::class -> MUTABLE_SET
- Map::class -> MUTABLE_MAP
- Map.Entry::class -> MUTABLE_MAP_ENTRY
- else -> error("No equivalent mutable Kotlin interop found for `$this`.")
- }
- return XClassName(java, kotlin, XNullability.NONNULL)
-}
-
-private fun getBoxedJClassName(klass: Class<*>): JClassName =
- when (klass) {
- java.lang.Void.TYPE -> JTypeName.VOID.box()
- java.lang.Boolean.TYPE -> JTypeName.BOOLEAN.box()
- java.lang.Byte.TYPE -> JTypeName.BYTE.box()
- java.lang.Short.TYPE -> JTypeName.SHORT.box()
- java.lang.Integer.TYPE -> JTypeName.INT.box()
- java.lang.Long.TYPE -> JTypeName.LONG.box()
- java.lang.Character.TYPE -> JTypeName.CHAR.box()
- java.lang.Float.TYPE -> JTypeName.FLOAT.box()
- java.lang.Double.TYPE -> JTypeName.DOUBLE.box()
- else -> error("Can't get JTypeName from java.lang.Class: $klass")
- }
- as JClassName
-
-/**
* Creates a [XTypeName] whose JavaPoet name is a primitive name and KotlinPoet is the interop type.
*
* This function is useful since [asClassName] only supports creating class names and specifically