Merge "Generating Kotlin in DataSourceFactoryQueryResultBinder and PositionalDataSourceQueryResultBinder." into androidx-main
diff --git a/room/room-compiler/src/main/kotlin/androidx/room/ext/xpoet_ext.kt b/room/room-compiler/src/main/kotlin/androidx/room/ext/xpoet_ext.kt
index a0a0a64..5ae096f 100644
--- a/room/room-compiler/src/main/kotlin/androidx/room/ext/xpoet_ext.kt
+++ b/room/room-compiler/src/main/kotlin/androidx/room/ext/xpoet_ext.kt
@@ -83,8 +83,7 @@
XClassName.get("$ROOM_PACKAGE.util", "TableInfo", "Index")
val FTS_TABLE_INFO = XClassName.get("$ROOM_PACKAGE.util", "FtsTableInfo")
val VIEW_INFO = XClassName.get("$ROOM_PACKAGE.util", "ViewInfo")
- val LIMIT_OFFSET_DATA_SOURCE: ClassName =
- ClassName.get("$ROOM_PACKAGE.paging", "LimitOffsetDataSource")
+ val LIMIT_OFFSET_DATA_SOURCE = XClassName.get("$ROOM_PACKAGE.paging", "LimitOffsetDataSource")
val DB_UTIL = XClassName.get("$ROOM_PACKAGE.util", "DBUtil")
val CURSOR_UTIL = XClassName.get("$ROOM_PACKAGE.util", "CursorUtil")
val MIGRATION = XClassName.get("$ROOM_PACKAGE.migration", "Migration")
@@ -99,8 +98,7 @@
ClassName.get(PAGING_PACKAGE, "DataSource")
val POSITIONAL_DATA_SOURCE: ClassName =
ClassName.get(PAGING_PACKAGE, "PositionalDataSource")
- val DATA_SOURCE_FACTORY: ClassName =
- ClassName.get(PAGING_PACKAGE, "DataSource", "Factory")
+ val DATA_SOURCE_FACTORY = XClassName.get(PAGING_PACKAGE, "DataSource", "Factory")
val PAGING_SOURCE = XClassName.get(PAGING_PACKAGE, "PagingSource")
val LISTENABLE_FUTURE_PAGING_SOURCE =
XClassName.get(PAGING_PACKAGE, "ListenableFuturePagingSource")
diff --git a/room/room-compiler/src/main/kotlin/androidx/room/solver/binderprovider/DataSourceFactoryQueryResultBinderProvider.kt b/room/room-compiler/src/main/kotlin/androidx/room/solver/binderprovider/DataSourceFactoryQueryResultBinderProvider.kt
index 88dabbe..71827d3 100644
--- a/room/room-compiler/src/main/kotlin/androidx/room/solver/binderprovider/DataSourceFactoryQueryResultBinderProvider.kt
+++ b/room/room-compiler/src/main/kotlin/androidx/room/solver/binderprovider/DataSourceFactoryQueryResultBinderProvider.kt
@@ -31,7 +31,7 @@
class DataSourceFactoryQueryResultBinderProvider(val context: Context) : QueryResultBinderProvider {
private val dataSourceFactoryType: XRawType? by lazy {
- context.processingEnv.findType(PagingTypeNames.DATA_SOURCE_FACTORY)?.rawType
+ context.processingEnv.findType(PagingTypeNames.DATA_SOURCE_FACTORY.canonicalName)?.rawType
}
override fun provide(
diff --git a/room/room-compiler/src/main/kotlin/androidx/room/solver/query/result/DataSourceFactoryQueryResultBinder.kt b/room/room-compiler/src/main/kotlin/androidx/room/solver/query/result/DataSourceFactoryQueryResultBinder.kt
index e8246ad..ca1736b 100644
--- a/room/room-compiler/src/main/kotlin/androidx/room/solver/query/result/DataSourceFactoryQueryResultBinder.kt
+++ b/room/room-compiler/src/main/kotlin/androidx/room/solver/query/result/DataSourceFactoryQueryResultBinder.kt
@@ -16,22 +16,19 @@
package androidx.room.solver.query.result
+import androidx.room.compiler.codegen.VisibilityModifier
+import androidx.room.compiler.codegen.XFunSpec
import androidx.room.compiler.codegen.XPropertySpec
-import androidx.room.ext.L
+import androidx.room.compiler.codegen.XTypeName
+import androidx.room.compiler.codegen.XTypeSpec
import androidx.room.ext.PagingTypeNames
-import androidx.room.ext.typeName
import androidx.room.solver.CodeGenScope
-import com.squareup.javapoet.MethodSpec
-import com.squareup.javapoet.ParameterizedTypeName
-import com.squareup.javapoet.TypeName
-import com.squareup.javapoet.TypeSpec
-import javax.lang.model.element.Modifier
class DataSourceFactoryQueryResultBinder(
val positionalDataSourceQueryResultBinder: PositionalDataSourceQueryResultBinder
) : QueryResultBinder(positionalDataSourceQueryResultBinder.listAdapter) {
- val typeName: TypeName = positionalDataSourceQueryResultBinder.itemTypeName
+ val typeName: XTypeName = positionalDataSourceQueryResultBinder.itemTypeName
override fun convertAndReturn(
roomSQLiteQueryVar: String,
@@ -40,48 +37,51 @@
inTransaction: Boolean,
scope: CodeGenScope
) {
- scope.builder().apply {
- val pagedListProvider = TypeSpec.anonymousClassBuilder("")
+ scope.builder.apply {
+ val pagedListProvider = XTypeSpec.anonymousClassBuilder(language)
.apply {
superclass(
- ParameterizedTypeName.get(
- PagingTypeNames.DATA_SOURCE_FACTORY,
- Integer::class.typeName,
+ PagingTypeNames.DATA_SOURCE_FACTORY.parametrizedBy(
+ XTypeName.BOXED_INT,
typeName
)
)
-
- addMethod(
- createCreateMethod(
- roomSQLiteQueryVar = roomSQLiteQueryVar,
- dbProperty = dbProperty,
- inTransaction = inTransaction,
- scope = scope
- )
+ addCreateMethod(
+ roomSQLiteQueryVar = roomSQLiteQueryVar,
+ dbProperty = dbProperty,
+ inTransaction = inTransaction,
+ scope = scope
)
}
.build()
- addStatement("return $L", pagedListProvider)
+ addStatement("return %L", pagedListProvider)
}
}
- private fun createCreateMethod(
+ private fun XTypeSpec.Builder.addCreateMethod(
roomSQLiteQueryVar: String,
dbProperty: XPropertySpec,
inTransaction: Boolean,
scope: CodeGenScope
- ): MethodSpec = MethodSpec.methodBuilder("create").apply {
- addAnnotation(Override::class.java)
- addModifiers(Modifier.PUBLIC)
- returns(positionalDataSourceQueryResultBinder.typeName)
- val countedBinderScope = scope.fork()
- positionalDataSourceQueryResultBinder.convertAndReturn(
- roomSQLiteQueryVar = roomSQLiteQueryVar,
- canReleaseQuery = true,
- dbProperty = dbProperty,
- inTransaction = inTransaction,
- scope = countedBinderScope
+ ) {
+ addFunction(
+ XFunSpec.builder(
+ language = language,
+ name = "create",
+ visibility = VisibilityModifier.PUBLIC,
+ isOverride = true
+ ).apply {
+ returns(positionalDataSourceQueryResultBinder.typeName)
+ val countedBinderScope = scope.fork()
+ positionalDataSourceQueryResultBinder.convertAndReturn(
+ roomSQLiteQueryVar = roomSQLiteQueryVar,
+ canReleaseQuery = true,
+ dbProperty = dbProperty,
+ inTransaction = inTransaction,
+ scope = countedBinderScope
+ )
+ addCode(countedBinderScope.generate())
+ }.build()
)
- addCode(countedBinderScope.builder().build())
- }.build()
+ }
}
diff --git a/room/room-compiler/src/main/kotlin/androidx/room/solver/query/result/PositionalDataSourceQueryResultBinder.kt b/room/room-compiler/src/main/kotlin/androidx/room/solver/query/result/PositionalDataSourceQueryResultBinder.kt
index d5b08e8..94725a6 100644
--- a/room/room-compiler/src/main/kotlin/androidx/room/solver/query/result/PositionalDataSourceQueryResultBinder.kt
+++ b/room/room-compiler/src/main/kotlin/androidx/room/solver/query/result/PositionalDataSourceQueryResultBinder.kt
@@ -16,20 +16,16 @@
package androidx.room.solver.query.result
+import androidx.room.compiler.codegen.VisibilityModifier
+import androidx.room.compiler.codegen.XFunSpec
+import androidx.room.compiler.codegen.XFunSpec.Builder.Companion.addStatement
import androidx.room.compiler.codegen.XPropertySpec
-import androidx.room.compiler.codegen.toJavaPoet
+import androidx.room.compiler.codegen.XTypeName
+import androidx.room.compiler.codegen.XTypeSpec
import androidx.room.ext.AndroidTypeNames.CURSOR
import androidx.room.ext.CommonTypeNames.LIST
-import androidx.room.ext.L
-import androidx.room.ext.N
import androidx.room.ext.RoomTypeNames
import androidx.room.solver.CodeGenScope
-import com.squareup.javapoet.MethodSpec
-import com.squareup.javapoet.ParameterSpec
-import com.squareup.javapoet.ParameterizedTypeName
-import com.squareup.javapoet.TypeName
-import com.squareup.javapoet.TypeSpec
-import javax.lang.model.element.Modifier
/**
* Used by Paging2 pipeline
@@ -38,11 +34,9 @@
val listAdapter: ListQueryResultAdapter?,
val tableNames: Set<String>,
) : QueryResultBinder(listAdapter) {
- val itemTypeName: TypeName =
- listAdapter?.rowAdapters?.firstOrNull()?.out?.typeName ?: TypeName.OBJECT
- val typeName: ParameterizedTypeName = ParameterizedTypeName.get(
- RoomTypeNames.LIMIT_OFFSET_DATA_SOURCE, itemTypeName
- )
+ val itemTypeName: XTypeName =
+ listAdapter?.rowAdapters?.firstOrNull()?.out?.asTypeName() ?: XTypeName.ANY_OBJECT
+ val typeName: XTypeName = RoomTypeNames.LIMIT_OFFSET_DATA_SOURCE.parametrizedBy(itemTypeName)
override fun convertAndReturn(
roomSQLiteQueryVar: String,
@@ -51,35 +45,45 @@
inTransaction: Boolean,
scope: CodeGenScope
) {
- val dbField = dbProperty.toJavaPoet()
// first comma for table names comes from the string since it might be empty in which case
// we don't need a comma. If list is empty, this prevents generating bad code (it is still
// an error to have empty list but that is already reported while item is processed)
val tableNamesList = tableNames.joinToString("") { ", \"$it\"" }
- val spec = TypeSpec.anonymousClassBuilder(
- "$N, $L, $L, $L $L",
- dbField, roomSQLiteQueryVar, inTransaction, true, tableNamesList
+ val spec = XTypeSpec.anonymousClassBuilder(
+ language = scope.language,
+ "%N, %L, %L, %L%L",
+ dbProperty,
+ roomSQLiteQueryVar,
+ inTransaction,
+ true,
+ tableNamesList
).apply {
superclass(typeName)
- addMethod(createConvertRowsMethod(scope))
+ addConvertRowsMethod(scope)
}.build()
- scope.builder().apply {
- addStatement("return $L", spec)
- }
+ scope.builder.addStatement("return %L", spec)
}
- private fun createConvertRowsMethod(scope: CodeGenScope): MethodSpec =
- MethodSpec.methodBuilder("convertRows").apply {
- addAnnotation(Override::class.java)
- addModifiers(Modifier.PROTECTED)
- returns(ParameterizedTypeName.get(LIST.toJavaPoet(), itemTypeName))
- val cursorParam = ParameterSpec.builder(CURSOR.toJavaPoet(), "cursor")
- .build()
- addParameter(cursorParam)
- val resultVar = scope.getTmpVar("_res")
- val rowsScope = scope.fork()
- listAdapter?.convert(resultVar, cursorParam.name, rowsScope)
- addCode(rowsScope.builder().build())
- addStatement("return $L", resultVar)
- }.build()
+ private fun XTypeSpec.Builder.addConvertRowsMethod(scope: CodeGenScope) {
+ addFunction(
+ XFunSpec.builder(
+ language = language,
+ name = "convertRows",
+ visibility = VisibilityModifier.PROTECTED,
+ isOverride = true
+ ).apply {
+ returns(LIST.parametrizedBy(itemTypeName))
+ val cursorParamName = "cursor"
+ addParameter(
+ CURSOR,
+ cursorParamName
+ )
+ val resultVar = scope.getTmpVar("_res")
+ val rowsScope = scope.fork()
+ listAdapter?.convert(resultVar, cursorParamName, rowsScope)
+ addCode(rowsScope.generate())
+ addStatement("return %L", resultVar)
+ }.build()
+ )
+ }
}
diff --git a/room/room-compiler/src/test/kotlin/androidx/room/processor/QueryMethodProcessorTest.kt b/room/room-compiler/src/test/kotlin/androidx/room/processor/QueryMethodProcessorTest.kt
index 4cd4627..2419724 100644
--- a/room/room-compiler/src/test/kotlin/androidx/room/processor/QueryMethodProcessorTest.kt
+++ b/room/room-compiler/src/test/kotlin/androidx/room/processor/QueryMethodProcessorTest.kt
@@ -30,6 +30,7 @@
import androidx.room.compiler.processing.util.runProcessorTest
import androidx.room.ext.CommonTypeNames
import androidx.room.ext.CommonTypeNames.LIST
+import androidx.room.ext.CommonTypeNames.STRING
import androidx.room.ext.GuavaUtilConcurrentTypeNames
import androidx.room.ext.KotlinTypeNames
import androidx.room.ext.LifecyclesTypeNames
@@ -646,17 +647,17 @@
singleQueryMethod<ReadQueryMethod>(
"""
@Query("select name from user")
- abstract ${PagingTypeNames.DATA_SOURCE_FACTORY}<Integer, String>
+ abstract ${PagingTypeNames.DATA_SOURCE_FACTORY.canonicalName}<Integer, String>
nameDataSourceFactory();
"""
) { parsedQuery, _ ->
assertThat(
- parsedQuery.returnType.typeName,
+ parsedQuery.returnType.asTypeName(),
`is`(
- ParameterizedTypeName.get(
- PagingTypeNames.DATA_SOURCE_FACTORY,
- Integer::class.typeName, String::class.typeName
- ) as TypeName
+ PagingTypeNames.DATA_SOURCE_FACTORY.parametrizedBy(
+ XTypeName.BOXED_INT,
+ STRING
+ )
)
)
assertThat(
@@ -675,17 +676,17 @@
singleQueryMethod<ReadQueryMethod>(
"""
@Query("select name from User u LEFT OUTER JOIN Book b ON u.uid == b.uid")
- abstract ${PagingTypeNames.DATA_SOURCE_FACTORY}<Integer, String>
+ abstract ${PagingTypeNames.DATA_SOURCE_FACTORY.canonicalName}<Integer, String>
nameDataSourceFactory();
"""
) { parsedQuery, _ ->
assertThat(
- parsedQuery.returnType.typeName,
+ parsedQuery.returnType.asTypeName(),
`is`(
- ParameterizedTypeName.get(
- PagingTypeNames.DATA_SOURCE_FACTORY,
- Integer::class.typeName, String::class.typeName
- ) as TypeName
+ PagingTypeNames.DATA_SOURCE_FACTORY.parametrizedBy(
+ XTypeName.BOXED_INT,
+ STRING
+ )
)
)
assertThat(
diff --git a/room/room-compiler/src/test/kotlin/androidx/room/processor/RawQueryMethodProcessorTest.kt b/room/room-compiler/src/test/kotlin/androidx/room/processor/RawQueryMethodProcessorTest.kt
index 325996b..549ec1c 100644
--- a/room/room-compiler/src/test/kotlin/androidx/room/processor/RawQueryMethodProcessorTest.kt
+++ b/room/room-compiler/src/test/kotlin/androidx/room/processor/RawQueryMethodProcessorTest.kt
@@ -137,7 +137,7 @@
singleQueryMethod(
"""
@RawQuery
- abstract public ${PagingTypeNames.DATA_SOURCE_FACTORY}<Integer, User> getOne();
+ abstract public ${PagingTypeNames.DATA_SOURCE_FACTORY.canonicalName}<Integer, User> getOne();
"""
) { _, invocation ->
invocation.assertCompilationResult {
diff --git a/room/room-compiler/src/test/kotlin/androidx/room/testing/test_util.kt b/room/room-compiler/src/test/kotlin/androidx/room/testing/test_util.kt
index 17d7b1a..0cb969c 100644
--- a/room/room-compiler/src/test/kotlin/androidx/room/testing/test_util.kt
+++ b/room/room-compiler/src/test/kotlin/androidx/room/testing/test_util.kt
@@ -29,7 +29,6 @@
import androidx.room.ext.GuavaUtilConcurrentTypeNames
import androidx.room.ext.KotlinTypeNames
import androidx.room.ext.LifecyclesTypeNames
-import androidx.room.ext.PagingTypeNames
import androidx.room.ext.ReactiveStreamsTypeNames
import androidx.room.ext.RoomGuavaTypeNames
import androidx.room.ext.RoomRxJava2TypeNames
@@ -194,13 +193,12 @@
}
val DATA_SOURCE_FACTORY by lazy {
- loadJavaCode("common/input/DataSource.java", "androidx.paging.DataSource")
+ loadKotlinCode("common/input/DataSource.kt")
}
val POSITIONAL_DATA_SOURCE by lazy {
- loadJavaCode(
- "common/input/PositionalDataSource.java",
- PagingTypeNames.POSITIONAL_DATA_SOURCE.toString()
+ loadKotlinCode(
+ "common/input/PositionalDataSource.kt"
)
}
diff --git a/room/room-compiler/src/test/kotlin/androidx/room/writer/DaoKotlinCodeGenTest.kt b/room/room-compiler/src/test/kotlin/androidx/room/writer/DaoKotlinCodeGenTest.kt
index 380deea..6a738b3 100644
--- a/room/room-compiler/src/test/kotlin/androidx/room/writer/DaoKotlinCodeGenTest.kt
+++ b/room/room-compiler/src/test/kotlin/androidx/room/writer/DaoKotlinCodeGenTest.kt
@@ -1586,4 +1586,38 @@
expectedFilePath = getTestGoldenPath(testName)
)
}
+
+ @Test
+ fun dataSource() {
+ val testName = object {}.javaClass.enclosingMethod!!.name
+ val src = Source.kotlin(
+ "MyDao.kt",
+ """
+ import androidx.room.*
+ import androidx.paging.*
+
+ @Dao
+ abstract class MyDao {
+ @Query("SELECT * from MyEntity")
+ abstract fun getDataSourceFactory(): DataSource.Factory<Int, MyEntity>
+ }
+
+ @Entity
+ data class MyEntity(
+ @PrimaryKey
+ val pk: Int,
+ val other: String
+ )
+ """.trimIndent()
+ )
+ runTest(
+ sources = listOf(
+ src,
+ databaseSrc,
+ COMMON.DATA_SOURCE_FACTORY,
+ COMMON.POSITIONAL_DATA_SOURCE
+ ),
+ expectedFilePath = getTestGoldenPath(testName)
+ )
+ }
}
\ No newline at end of file
diff --git a/room/room-compiler/src/test/test-data/common/input/DataSource.java b/room/room-compiler/src/test/test-data/common/input/DataSource.kt
similarity index 75%
rename from room/room-compiler/src/test/test-data/common/input/DataSource.java
rename to room/room-compiler/src/test/test-data/common/input/DataSource.kt
index 157750a..6fa77e8 100644
--- a/room/room-compiler/src/test/test-data/common/input/DataSource.java
+++ b/room/room-compiler/src/test/test-data/common/input/DataSource.kt
@@ -13,10 +13,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+package androidx.paging
-package androidx.paging;
-
-abstract public class DataSource<K, T> {
- public interface Factory<Key, Value> {
+public abstract class DataSource<Key : Any, Value : Any> {
+ public abstract class Factory<Key : Any, Value : Any> {
+ public abstract fun create(): DataSource<Key, Value>
}
-}
+}
\ No newline at end of file
diff --git a/room/room-compiler/src/test/test-data/common/input/PositionalDataSource.java b/room/room-compiler/src/test/test-data/common/input/PositionalDataSource.java
deleted file mode 100644
index ff5338a..0000000
--- a/room/room-compiler/src/test/test-data/common/input/PositionalDataSource.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package androidx.paging;
-
-public abstract class PositionalDataSource<T> extends DataSource<Integer, T> {
-
-}
\ No newline at end of file
diff --git a/room/room-compiler/src/test/test-data/common/input/PositionalDataSource.kt b/room/room-compiler/src/test/test-data/common/input/PositionalDataSource.kt
new file mode 100644
index 0000000..a837ed1
--- /dev/null
+++ b/room/room-compiler/src/test/test-data/common/input/PositionalDataSource.kt
@@ -0,0 +1,3 @@
+package androidx.paging
+
+abstract class PositionalDataSource<T : Any> : DataSource<Int, T>()
\ No newline at end of file
diff --git a/room/room-compiler/src/test/test-data/kotlinCodeGen/dataSource.kt b/room/room-compiler/src/test/test-data/kotlinCodeGen/dataSource.kt
new file mode 100644
index 0000000..25c7425
--- /dev/null
+++ b/room/room-compiler/src/test/test-data/kotlinCodeGen/dataSource.kt
@@ -0,0 +1,57 @@
+import android.database.Cursor
+import androidx.paging.DataSource
+import androidx.room.RoomDatabase
+import androidx.room.RoomSQLiteQuery
+import androidx.room.RoomSQLiteQuery.Companion.acquire
+import androidx.room.paging.LimitOffsetDataSource
+import androidx.room.util.getColumnIndexOrThrow
+import java.lang.Class
+import java.util.ArrayList
+import javax.`annotation`.processing.Generated
+import kotlin.Int
+import kotlin.String
+import kotlin.Suppress
+import kotlin.collections.List
+import kotlin.collections.MutableList
+import kotlin.jvm.JvmStatic
+
+@Generated(value = ["androidx.room.RoomProcessor"])
+@Suppress(names = ["UNCHECKED_CAST", "DEPRECATION"])
+public class MyDao_Impl(
+ __db: RoomDatabase,
+) : MyDao() {
+ private val __db: RoomDatabase
+ init {
+ this.__db = __db
+ }
+
+ public override fun getDataSourceFactory(): DataSource.Factory<Int, MyEntity> {
+ val _sql: String = "SELECT * from MyEntity"
+ val _statement: RoomSQLiteQuery = acquire(_sql, 0)
+ return object : DataSource.Factory<Int, MyEntity>() {
+ public override fun create(): LimitOffsetDataSource<MyEntity> = object :
+ LimitOffsetDataSource<MyEntity>(__db, _statement, false, true, "MyEntity") {
+ protected override fun convertRows(cursor: Cursor): List<MyEntity> {
+ val _cursorIndexOfPk: Int = getColumnIndexOrThrow(cursor, "pk")
+ val _cursorIndexOfOther: Int = getColumnIndexOrThrow(cursor, "other")
+ val _res: MutableList<MyEntity> = ArrayList<MyEntity>(cursor.getCount())
+ while (cursor.moveToNext()) {
+ val _item: MyEntity
+ val _tmpPk: Int
+ _tmpPk = cursor.getInt(_cursorIndexOfPk)
+ val _tmpOther: String
+ _tmpOther = cursor.getString(_cursorIndexOfOther)
+ _item = MyEntity(_tmpPk,_tmpOther)
+ _res.add(_item)
+ }
+ return _res
+ }
+ }
+ }
+ }
+
+ public companion object {
+ @JvmStatic
+ public fun getRequiredConverters(): List<Class<*>> = emptyList()
+ }
+}
\ No newline at end of file