Merge "Update TypeConverters API to be more explicit" into androidx-main
diff --git a/room/room-compiler/src/main/kotlin/androidx/room/parser/SqlParser.kt b/room/room-compiler/src/main/kotlin/androidx/room/parser/SqlParser.kt
index a9eeb8c..5241975 100644
--- a/room/room-compiler/src/main/kotlin/androidx/room/parser/SqlParser.kt
+++ b/room/room-compiler/src/main/kotlin/androidx/room/parser/SqlParser.kt
@@ -256,7 +256,7 @@
REAL,
BLOB;
- fun getTypeMirrors(env: XProcessingEnv): List<XType> {
+ fun getTypeMirrors(env: XProcessingEnv): List<XType>? {
return when (this) {
TEXT -> withBoxedAndNullableTypes(env, CommonTypeNames.STRING)
INTEGER -> withBoxedAndNullableTypes(
@@ -265,7 +265,7 @@
)
REAL -> withBoxedAndNullableTypes(env, TypeName.DOUBLE, TypeName.FLOAT)
BLOB -> withBoxedAndNullableTypes(env, ArrayTypeName.of(TypeName.BYTE))
- else -> emptyList()
+ else -> null
}
}
diff --git a/room/room-compiler/src/main/kotlin/androidx/room/solver/TypeAdapterStore.kt b/room/room-compiler/src/main/kotlin/androidx/room/solver/TypeAdapterStore.kt
index db3b91e..7af6697 100644
--- a/room/room-compiler/src/main/kotlin/androidx/room/solver/TypeAdapterStore.kt
+++ b/room/room-compiler/src/main/kotlin/androidx/room/solver/TypeAdapterStore.kt
@@ -122,9 +122,8 @@
* first type adapter has the highest priority
*/
private val columnTypeAdapters: List<ColumnTypeAdapter>,
-
- private val typeConverterStore: TypeConverterStore,
-
+ @VisibleForTesting
+ internal val typeConverterStore: TypeConverterStore,
private val builtInConverterFlags: BuiltInConverterFlags
) {
@@ -177,7 +176,10 @@
.forEach(::addTypeConverter)
return TypeAdapterStore(
context = context, columnTypeAdapters = adapters,
- typeConverterStore = TypeConverterStore(converters),
+ typeConverterStore = TypeConverterStore(
+ typeConverters = converters,
+ knownColumnTypes = adapters.map { it.out }
+ ),
builtInConverterFlags = builtInConverterFlags
)
}
@@ -218,11 +220,6 @@
add(InstantDeleteOrUpdateMethodBinderProvider(context))
}
- // type mirrors that be converted into columns w/o an extra converter
- private val knownColumnTypeMirrors by lazy {
- columnTypeAdapters.map { it.out }
- }
-
/**
* Searches 1 way to bind a value into a statement.
*/
@@ -239,8 +236,11 @@
}
fun findTypeConverterAdapter(): ColumnTypeAdapter? {
- val targetTypes = targetTypeMirrorsFor(affinity)
- val binder = findTypeConverter(input, targetTypes) ?: return null
+ val targetTypes = affinity?.getTypeMirrors(context.processingEnv)
+ val binder = typeConverterStore.findConverterIntoStatement(
+ input = input,
+ columnTypes = targetTypes
+ ) ?: return null
// columnAdapter should not be null but we are receiving errors on crash in `first()` so
// this safeguard allows us to dispatch the real problem to the user (e.g. why we couldn't
// find the right adapter)
@@ -260,18 +260,6 @@
}
/**
- * Returns which entities targets the given affinity.
- */
- private fun targetTypeMirrorsFor(affinity: SQLTypeAffinity?): List<XType> {
- val specifiedTargets = affinity?.getTypeMirrors(context.processingEnv)
- return if (specifiedTargets == null || specifiedTargets.isEmpty()) {
- knownColumnTypeMirrors
- } else {
- specifiedTargets
- }
- }
-
- /**
* Searches 1 way to read it from cursor
*/
fun findCursorValueReader(output: XType, affinity: SQLTypeAffinity?): CursorValueReader? {
@@ -285,8 +273,11 @@
}
fun findTypeConverterAdapter(): ColumnTypeAdapter? {
- val targetTypes = targetTypeMirrorsFor(affinity)
- val converter = findTypeConverter(targetTypes, output) ?: return null
+ val targetTypes = affinity?.getTypeMirrors(context.processingEnv)
+ val converter = typeConverterStore.findConverterFromCursor(
+ columnTypes = targetTypes,
+ output = output
+ ) ?: return null
return CompositeAdapter(
output,
getAllColumnAdapters(converter.from).first(), null, converter
@@ -308,14 +299,6 @@
}
/**
- * Tries to reverse the converter going through the same nodes, if possible.
- */
- @VisibleForTesting
- fun reverse(converter: TypeConverter): TypeConverter? {
- return typeConverterStore.reverse(converter)
- }
-
- /**
* Finds a two way converter, if you need 1 way, use findStatementValueBinder or
* findCursorValueReader.
*/
@@ -333,11 +316,14 @@
}
fun findTypeConverterAdapter(): ColumnTypeAdapter? {
- val targetTypes = targetTypeMirrorsFor(affinity)
- val intoStatement = findTypeConverter(out, targetTypes) ?: return null
+ val targetTypes = affinity?.getTypeMirrors(context.processingEnv)
+ val intoStatement = typeConverterStore.findConverterIntoStatement(
+ input = out,
+ columnTypes = targetTypes
+ ) ?: return null
// ok found a converter, try the reverse now
- val fromCursor = reverse(intoStatement)
- ?: findTypeConverter(intoStatement.to, out) ?: return null
+ val fromCursor = typeConverterStore.reverse(intoStatement)
+ ?: typeConverterStore.findTypeConverter(intoStatement.to, out) ?: return null
return CompositeAdapter(
out, getAllColumnAdapters(intoStatement.to).first(), intoStatement, fromCursor
)
@@ -377,10 +363,6 @@
}
}
- fun findTypeConverter(input: XType, output: XType): TypeConverter? {
- return typeConverterStore.findTypeConverter(listOf(input), listOf(output))
- }
-
fun findDeleteOrUpdateMethodBinder(typeMirror: XType): DeleteOrUpdateMethodBinder {
return deleteOrUpdateBinderProvider.first {
it.matches(typeMirror)
@@ -811,14 +793,6 @@
}
}
- private fun findTypeConverter(input: XType, outputs: List<XType>): TypeConverter? {
- return typeConverterStore.findTypeConverter(listOf(input), outputs)
- }
-
- private fun findTypeConverter(input: List<XType>, output: XType): TypeConverter? {
- return typeConverterStore.findTypeConverter(input, listOf(output))
- }
-
private fun getAllColumnAdapters(input: XType): List<ColumnTypeAdapter> {
return columnTypeAdapters.filter {
input.isSameType(it.out)
diff --git a/room/room-compiler/src/main/kotlin/androidx/room/solver/TypeConverterStore.kt b/room/room-compiler/src/main/kotlin/androidx/room/solver/TypeConverterStore.kt
index 43ac3e3..c1184c5 100644
--- a/room/room-compiler/src/main/kotlin/androidx/room/solver/TypeConverterStore.kt
+++ b/room/room-compiler/src/main/kotlin/androidx/room/solver/TypeConverterStore.kt
@@ -28,15 +28,58 @@
* provided type converters.
*/
class TypeConverterStore(
- private val typeConverters: List<TypeConverter>
+ /**
+ * Available TypeConverters
+ */
+ private val typeConverters: List<TypeConverter>,
+ /**
+ * List of types that can be saved into db/read from without a converter.
+ */
+ private val knownColumnTypes: List<XType>
) {
/**
- * Finds a type converter that can conver one of the input valuese to one of the output values.
+ * Finds a [TypeConverter] (might be composite) that can convert the given [input] type into
+ * one of the given [columnTypes]. If [columnTypes] is not specified, targets all
+ * [knownColumnTypes].
+ */
+ fun findConverterIntoStatement(
+ input: XType,
+ columnTypes: List<XType>? = null
+ ) = findTypeConverter(
+ inputs = listOf(input),
+ outputs = columnTypes ?: knownColumnTypes
+ )
+
+ /**
+ * Finds a [TypeConverter] (might be composite) that can convert the given [columnTypes] into
+ * the [output] type. If [columnTypes] is not specified, uses all [knownColumnTypes].
+ */
+ fun findConverterFromCursor(
+ columnTypes: List<XType>? = null,
+ output: XType
+ ) = findTypeConverter(
+ inputs = columnTypes ?: knownColumnTypes,
+ outputs = listOf(output)
+ )
+
+ /**
+ * Finds a [TypeConverter] from [input] to [output].
+ */
+ fun findTypeConverter(
+ input: XType,
+ output: XType
+ ) = findTypeConverter(
+ inputs = listOf(input),
+ outputs = listOf(output)
+ )
+
+ /**
+ * Finds a type converter that can convert one of the input values to one of the output values.
*
* When multiple conversion paths are possible, shortest path (least amount of conversion) is
* preferred.
*/
- fun findTypeConverter(
+ private fun findTypeConverter(
inputs: List<XType>,
outputs: List<XType>
): TypeConverter? {
@@ -119,6 +162,7 @@
}
}
}
+
/**
* Tries to reverse the converter going through the same nodes, if possible.
*/
diff --git a/room/room-compiler/src/test/kotlin/androidx/room/parser/SQLTypeAffinityTest.kt b/room/room-compiler/src/test/kotlin/androidx/room/parser/SQLTypeAffinityTest.kt
index 9f3f8d6..fff0299 100644
--- a/room/room-compiler/src/test/kotlin/androidx/room/parser/SQLTypeAffinityTest.kt
+++ b/room/room-compiler/src/test/kotlin/androidx/room/parser/SQLTypeAffinityTest.kt
@@ -49,7 +49,7 @@
}
val result = SQLTypeAffinity.values().associate {
- it to it.getTypeMirrors(invocation.processingEnv).map(XType::toSignature)
+ it to it.getTypeMirrors(invocation.processingEnv)?.map(XType::toSignature)
}
assertThat(result).containsExactlyEntriesIn(
if (invocation.isKsp) KSP_MAPPING
@@ -60,7 +60,7 @@
companion object {
private val KSP_MAPPING = mapOf(
- SQLTypeAffinity.NULL to listOf(),
+ SQLTypeAffinity.NULL to null,
SQLTypeAffinity.TEXT to listOf(
"java.lang.String!!",
"java.lang.String?"
@@ -89,7 +89,7 @@
)
)
private val JAVAC_MAPPING = mapOf(
- SQLTypeAffinity.NULL to listOf(),
+ SQLTypeAffinity.NULL to null,
SQLTypeAffinity.TEXT to listOf(
"java.lang.String"
),
diff --git a/room/room-compiler/src/test/kotlin/androidx/room/solver/TypeAdapterStoreTest.kt b/room/room-compiler/src/test/kotlin/androidx/room/solver/TypeAdapterStoreTest.kt
index 8919793..5a958c7 100644
--- a/room/room-compiler/src/test/kotlin/androidx/room/solver/TypeAdapterStoreTest.kt
+++ b/room/room-compiler/src/test/kotlin/androidx/room/solver/TypeAdapterStoreTest.kt
@@ -421,12 +421,12 @@
)
)
- val converter = store.findTypeConverter(
+ val converter = store.typeConverterStore.findTypeConverter(
binders[0].from,
invocation.context.COMMON_TYPES.STRING
)
assertThat(converter, notNullValue())
- assertThat(store.reverse(converter!!), `is`(binders[1]))
+ assertThat(store.typeConverterStore.reverse(converter!!), `is`(binders[1]))
}
}
@@ -449,12 +449,12 @@
val stmtBinder = store.findStatementValueBinder(binders[0].from, null)
assertThat(stmtBinder, notNullValue())
- val converter = store.findTypeConverter(
+ val converter = store.typeConverterStore.findTypeConverter(
binders[0].from,
invocation.context.COMMON_TYPES.STRING
)
assertThat(converter, notNullValue())
- assertThat(store.reverse(converter!!), nullValue())
+ assertThat(store.typeConverterStore.reverse(converter!!), nullValue())
}
}
diff --git a/room/room-compiler/src/test/kotlin/androidx/room/solver/TypeConverterStoreTest.kt b/room/room-compiler/src/test/kotlin/androidx/room/solver/TypeConverterStoreTest.kt
index 001b1b2..18c67d2 100644
--- a/room/room-compiler/src/test/kotlin/androidx/room/solver/TypeConverterStoreTest.kt
+++ b/room/room-compiler/src/test/kotlin/androidx/room/solver/TypeConverterStoreTest.kt
@@ -70,7 +70,7 @@
invocation.context,
BuiltInConverterFlags.DEFAULT,
converters.map(::CustomTypeConverterWrapper)
- )
+ ).typeConverterStore
fun findConverter(from: String, to: String): String? {
val input = invocation.processingEnv.requireType(from)