12259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar/*
22259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar * Copyright (C) 2016 The Android Open Source Project
32259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar *
42259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar * Licensed under the Apache License, Version 2.0 (the "License");
52259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar * you may not use this file except in compliance with the License.
62259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar * You may obtain a copy of the License at
72259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar *
82259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar *      http://www.apache.org/licenses/LICENSE-2.0
92259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar *
102259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar * Unless required by applicable law or agreed to in writing, software
112259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar * distributed under the License is distributed on an "AS IS" BASIS,
122259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar * See the License for the specific language governing permissions and
142259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar * limitations under the License.
152259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar */
162259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar
1764db0cc15b78b62a1d44a70fc8b4552e660d952cYigit Boyarpackage android.arch.persistence.room.solver
182259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar
193c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyarimport COMMON
2064db0cc15b78b62a1d44a70fc8b4552e660d952cYigit Boyarimport android.arch.persistence.room.Entity
2164db0cc15b78b62a1d44a70fc8b4552e660d952cYigit Boyarimport android.arch.persistence.room.ext.L
2264db0cc15b78b62a1d44a70fc8b4552e660d952cYigit Boyarimport android.arch.persistence.room.ext.LifecyclesTypeNames
239fd8e6171bbdc37f5516fe15b2d96f4ae926ef1aChris Craikimport android.arch.persistence.room.ext.PagingTypeNames
2464db0cc15b78b62a1d44a70fc8b4552e660d952cYigit Boyarimport android.arch.persistence.room.ext.ReactiveStreamsTypeNames
2564db0cc15b78b62a1d44a70fc8b4552e660d952cYigit Boyarimport android.arch.persistence.room.ext.RoomTypeNames.STRING_UTIL
2664db0cc15b78b62a1d44a70fc8b4552e660d952cYigit Boyarimport android.arch.persistence.room.ext.RxJava2TypeNames
2764db0cc15b78b62a1d44a70fc8b4552e660d952cYigit Boyarimport android.arch.persistence.room.ext.T
281676c28584028f8427475745d7a779607af67ecbYigit Boyarimport android.arch.persistence.room.parser.SQLTypeAffinity
2964db0cc15b78b62a1d44a70fc8b4552e660d952cYigit Boyarimport android.arch.persistence.room.processor.Context
3064db0cc15b78b62a1d44a70fc8b4552e660d952cYigit Boyarimport android.arch.persistence.room.processor.ProcessorErrors
3124418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craikimport android.arch.persistence.room.solver.binderprovider.DataSourceQueryResultBinderProvider
329fd8e6171bbdc37f5516fe15b2d96f4ae926ef1aChris Craikimport android.arch.persistence.room.solver.binderprovider.FlowableQueryResultBinderProvider
339fd8e6171bbdc37f5516fe15b2d96f4ae926ef1aChris Craikimport android.arch.persistence.room.solver.binderprovider.LiveDataQueryResultBinderProvider
3424418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craikimport android.arch.persistence.room.solver.binderprovider.LivePagedListQueryResultBinderProvider
3564db0cc15b78b62a1d44a70fc8b4552e660d952cYigit Boyarimport android.arch.persistence.room.solver.types.CompositeAdapter
3664db0cc15b78b62a1d44a70fc8b4552e660d952cYigit Boyarimport android.arch.persistence.room.solver.types.TypeConverter
3764db0cc15b78b62a1d44a70fc8b4552e660d952cYigit Boyarimport android.arch.persistence.room.testing.TestInvocation
3864db0cc15b78b62a1d44a70fc8b4552e660d952cYigit Boyarimport android.arch.persistence.room.testing.TestProcessor
39ef346ae131affbba6345e00d833103acc5743c8aChris Craikimport android.arch.paging.DataSource
40abd098954d3fe996f336201ccb25884aaa34e07fYigit Boyarimport android.arch.paging.TiledDataSource
413c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyarimport com.google.auto.common.MoreTypes
422259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyarimport com.google.common.truth.Truth
432259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyarimport com.google.testing.compile.CompileTester
442259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyarimport com.google.testing.compile.JavaFileObjects
452259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyarimport com.google.testing.compile.JavaSourcesSubjectFactory
46aa82fce1d73394bdc7f4c2510cf94a3572032b24Yigit Boyarimport org.hamcrest.CoreMatchers.`is`
47aa82fce1d73394bdc7f4c2510cf94a3572032b24Yigit Boyarimport org.hamcrest.CoreMatchers.instanceOf
48aa82fce1d73394bdc7f4c2510cf94a3572032b24Yigit Boyarimport org.hamcrest.CoreMatchers.notNullValue
49fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyarimport org.hamcrest.CoreMatchers.nullValue
502259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyarimport org.hamcrest.MatcherAssert.assertThat
512259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyarimport org.junit.Test
522259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyarimport org.junit.runner.RunWith
532259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyarimport org.junit.runners.JUnit4
543c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyarimport simpleRun
55645abf12d5a13dae5c2271cedd0563a580871a2bYigit Boyarimport testCodeGenScope
562259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyarimport javax.annotation.processing.ProcessingEnvironment
572259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyarimport javax.lang.model.type.TypeKind
582259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar
592259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar@Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN")
602259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar@RunWith(JUnit4::class)
612259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyarclass TypeAdapterStoreTest {
622259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar    companion object {
632259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar        fun tmp(index: Int) = CodeGenScope._tmpVar(index)
642259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar    }
652259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar
662259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar    @Test
672259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar    fun testDirect() {
682259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar        singleRun { invocation ->
697a705bcaf6c86eae4c28e38f119289826a651e5bYigit Boyar            val store = TypeAdapterStore.create(Context(invocation.processingEnv))
702259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar            val primitiveType = invocation.processingEnv.typeUtils.getPrimitiveType(TypeKind.INT)
71275e7088223c097c1a2df718455bede42bc9efedYigit Boyar            val adapter = store.findColumnTypeAdapter(primitiveType, null)
722259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar            assertThat(adapter, notNullValue())
732259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar        }.compilesWithoutError()
742259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar    }
752259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar
762259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar    @Test
772259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar    fun testVia1TypeAdapter() {
782259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar        singleRun { invocation ->
797a705bcaf6c86eae4c28e38f119289826a651e5bYigit Boyar            val store = TypeAdapterStore.create(Context(invocation.processingEnv))
802259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar            val booleanType = invocation.processingEnv.typeUtils
812259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar                    .getPrimitiveType(TypeKind.BOOLEAN)
82275e7088223c097c1a2df718455bede42bc9efedYigit Boyar            val adapter = store.findColumnTypeAdapter(booleanType, null)
832259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar            assertThat(adapter, notNullValue())
842259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar            assertThat(adapter, instanceOf(CompositeAdapter::class.java))
85645abf12d5a13dae5c2271cedd0563a580871a2bYigit Boyar            val bindScope = testCodeGenScope()
86efaf86afac3163868eda7f91a1c04e3f6e6d7520Yigit Boyar            adapter!!.bindToStmt("stmt", "41", "fooVar", bindScope)
872259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar            assertThat(bindScope.generate().trim(), `is`("""
882259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar                    final int ${tmp(0)};
892259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar                    ${tmp(0)} = fooVar ? 1 : 0;
902259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar                    stmt.bindLong(41, ${tmp(0)});
912259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar                    """.trimIndent()))
922259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar
93645abf12d5a13dae5c2271cedd0563a580871a2bYigit Boyar            val cursorScope = testCodeGenScope()
94efaf86afac3163868eda7f91a1c04e3f6e6d7520Yigit Boyar            adapter.readFromCursor("res", "curs", "7", cursorScope)
952259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar            assertThat(cursorScope.generate().trim(), `is`("""
962259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar                    final int ${tmp(0)};
972259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar                    ${tmp(0)} = curs.getInt(7);
982259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar                    res = ${tmp(0)} != 0;
992259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar                    """.trimIndent()))
1002259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar        }.compilesWithoutError()
1012259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar    }
1022259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar
1032259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar    @Test
1042259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar    fun testVia2TypeAdapters() {
1052259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar        singleRun { invocation ->
1067a705bcaf6c86eae4c28e38f119289826a651e5bYigit Boyar            val store = TypeAdapterStore.create(Context(invocation.processingEnv),
107fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar                    pointTypeConverters(invocation.processingEnv))
1082259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar            val pointType = invocation.processingEnv.elementUtils
1092259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar                    .getTypeElement("foo.bar.Point").asType()
110275e7088223c097c1a2df718455bede42bc9efedYigit Boyar            val adapter = store.findColumnTypeAdapter(pointType, null)
1112259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar            assertThat(adapter, notNullValue())
1122259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar            assertThat(adapter, instanceOf(CompositeAdapter::class.java))
1132259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar
114645abf12d5a13dae5c2271cedd0563a580871a2bYigit Boyar            val bindScope = testCodeGenScope()
115efaf86afac3163868eda7f91a1c04e3f6e6d7520Yigit Boyar            adapter!!.bindToStmt("stmt", "41", "fooVar", bindScope)
1162259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar            assertThat(bindScope.generate().trim(), `is`("""
1178e543c445cb5559e579f54c1ac00d0ca83ec3fbbYigit Boyar                    final int ${tmp(0)};
1188e543c445cb5559e579f54c1ac00d0ca83ec3fbbYigit Boyar                    final boolean ${tmp(1)};
1198e543c445cb5559e579f54c1ac00d0ca83ec3fbbYigit Boyar                    ${tmp(1)} = foo.bar.Point.toBoolean(fooVar);
1208e543c445cb5559e579f54c1ac00d0ca83ec3fbbYigit Boyar                    ${tmp(0)} = ${tmp(1)} ? 1 : 0;
1218e543c445cb5559e579f54c1ac00d0ca83ec3fbbYigit Boyar                    stmt.bindLong(41, ${tmp(0)});
1222259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar                    """.trimIndent()))
1232259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar
124645abf12d5a13dae5c2271cedd0563a580871a2bYigit Boyar            val cursorScope = testCodeGenScope()
125efaf86afac3163868eda7f91a1c04e3f6e6d7520Yigit Boyar            adapter.readFromCursor("res", "curs", "11", cursorScope).toString()
1262259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar            assertThat(cursorScope.generate().trim(), `is`("""
1272259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar                    final int ${tmp(0)};
1282259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar                    ${tmp(0)} = curs.getInt(11);
1292259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar                    final boolean ${tmp(1)};
1302259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar                    ${tmp(1)} = ${tmp(0)} != 0;
1312259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar                    res = foo.bar.Point.fromBoolean(${tmp(1)});
1322259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar                    """.trimIndent()))
1332259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar        }.compilesWithoutError()
1342259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar    }
1352259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar
1362259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar    @Test
1371676c28584028f8427475745d7a779607af67ecbYigit Boyar    fun testDate() {
1381676c28584028f8427475745d7a779607af67ecbYigit Boyar        singleRun { (processingEnv) ->
1391676c28584028f8427475745d7a779607af67ecbYigit Boyar            val store = TypeAdapterStore.create(Context(processingEnv),
1401676c28584028f8427475745d7a779607af67ecbYigit Boyar                    dateTypeConverters(processingEnv))
1411676c28584028f8427475745d7a779607af67ecbYigit Boyar            val tDate = processingEnv.elementUtils.getTypeElement("java.util.Date").asType()
1421676c28584028f8427475745d7a779607af67ecbYigit Boyar            val adapter = store.findCursorValueReader(tDate, SQLTypeAffinity.INTEGER)
1431676c28584028f8427475745d7a779607af67ecbYigit Boyar            assertThat(adapter, notNullValue())
1441676c28584028f8427475745d7a779607af67ecbYigit Boyar            assertThat(adapter?.typeMirror(), `is`(tDate))
1451676c28584028f8427475745d7a779607af67ecbYigit Boyar            val bindScope = testCodeGenScope()
1461676c28584028f8427475745d7a779607af67ecbYigit Boyar            adapter!!.readFromCursor("outDate", "curs", "0", bindScope)
1471676c28584028f8427475745d7a779607af67ecbYigit Boyar            assertThat(bindScope.generate().trim(), `is`("""
1481676c28584028f8427475745d7a779607af67ecbYigit Boyar                final java.lang.Long _tmp;
1491676c28584028f8427475745d7a779607af67ecbYigit Boyar                if (curs.isNull(0)) {
1501676c28584028f8427475745d7a779607af67ecbYigit Boyar                  _tmp = null;
1511676c28584028f8427475745d7a779607af67ecbYigit Boyar                } else {
1521676c28584028f8427475745d7a779607af67ecbYigit Boyar                  _tmp = curs.getLong(0);
1531676c28584028f8427475745d7a779607af67ecbYigit Boyar                }
1541676c28584028f8427475745d7a779607af67ecbYigit Boyar                // convert Long to Date;
1551676c28584028f8427475745d7a779607af67ecbYigit Boyar            """.trimIndent()))
1561676c28584028f8427475745d7a779607af67ecbYigit Boyar        }.compilesWithoutError()
1571676c28584028f8427475745d7a779607af67ecbYigit Boyar    }
1581676c28584028f8427475745d7a779607af67ecbYigit Boyar
1591676c28584028f8427475745d7a779607af67ecbYigit Boyar    @Test
1602259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar    fun testIntList() {
1612259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar        singleRun { invocation ->
162fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar            val binders = createIntListToStringBinders(invocation)
1637a705bcaf6c86eae4c28e38f119289826a651e5bYigit Boyar            val store = TypeAdapterStore.create(Context(invocation.processingEnv), binders[0],
164fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar                    binders[1])
165fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar
166275e7088223c097c1a2df718455bede42bc9efedYigit Boyar            val adapter = store.findColumnTypeAdapter(binders[0].from, null)
1672259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar            assertThat(adapter, notNullValue())
1682259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar
169645abf12d5a13dae5c2271cedd0563a580871a2bYigit Boyar            val bindScope = testCodeGenScope()
170efaf86afac3163868eda7f91a1c04e3f6e6d7520Yigit Boyar            adapter!!.bindToStmt("stmt", "41", "fooVar", bindScope)
1712259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar            assertThat(bindScope.generate().trim(), `is`("""
17264db0cc15b78b62a1d44a70fc8b4552e660d952cYigit Boyar                final java.lang.String ${tmp(0)};
17364db0cc15b78b62a1d44a70fc8b4552e660d952cYigit Boyar                ${tmp(0)} = android.arch.persistence.room.util.StringUtil.joinIntoString(fooVar);
17464db0cc15b78b62a1d44a70fc8b4552e660d952cYigit Boyar                if (${tmp(0)} == null) {
17564db0cc15b78b62a1d44a70fc8b4552e660d952cYigit Boyar                  stmt.bindNull(41);
17664db0cc15b78b62a1d44a70fc8b4552e660d952cYigit Boyar                } else {
17764db0cc15b78b62a1d44a70fc8b4552e660d952cYigit Boyar                  stmt.bindString(41, ${tmp(0)});
17864db0cc15b78b62a1d44a70fc8b4552e660d952cYigit Boyar                }
17964db0cc15b78b62a1d44a70fc8b4552e660d952cYigit Boyar                """.trimIndent()))
180fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar
181fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar            val converter = store.findTypeConverter(binders[0].from,
182fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar                    invocation.context.COMMON_TYPES.STRING)
183fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar            assertThat(converter, notNullValue())
184fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar            assertThat(store.reverse(converter!!), `is`(binders[1]))
185fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar
1862259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar        }.compilesWithoutError()
1872259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar    }
1882259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar
189fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar    @Test
190fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar    fun testOneWayConversion() {
191fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar        singleRun { invocation ->
192fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar            val binders = createIntListToStringBinders(invocation)
1937a705bcaf6c86eae4c28e38f119289826a651e5bYigit Boyar            val store = TypeAdapterStore.create(Context(invocation.processingEnv), binders[0])
194275e7088223c097c1a2df718455bede42bc9efedYigit Boyar            val adapter = store.findColumnTypeAdapter(binders[0].from, null)
195fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar            assertThat(adapter, nullValue())
196fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar
197275e7088223c097c1a2df718455bede42bc9efedYigit Boyar            val stmtBinder = store.findStatementValueBinder(binders[0].from, null)
198fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar            assertThat(stmtBinder, notNullValue())
199fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar
200fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar            val converter = store.findTypeConverter(binders[0].from,
201fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar                    invocation.context.COMMON_TYPES.STRING)
202fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar            assertThat(converter, notNullValue())
203fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar            assertThat(store.reverse(converter!!), nullValue())
204fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar        }
205fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar    }
206fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar
2073c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar    @Test
2083c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar    fun testMissingRxRoom() {
2093c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar        simpleRun(jfos = *arrayOf(COMMON.PUBLISHER, COMMON.FLOWABLE)) { invocation ->
2103c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar            val publisherElement = invocation.processingEnv.elementUtils
2113c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar                    .getTypeElement(ReactiveStreamsTypeNames.PUBLISHER.toString())
2123c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar            assertThat(publisherElement, notNullValue())
2139fd8e6171bbdc37f5516fe15b2d96f4ae926ef1aChris Craik            assertThat(FlowableQueryResultBinderProvider(invocation.context).matches(
2143c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar                    MoreTypes.asDeclared(publisherElement.asType())), `is`(true))
2153c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar        }.failsToCompile().withErrorContaining(ProcessorErrors.MISSING_ROOM_RXJAVA2_ARTIFACT)
2163c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar    }
2173c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar
2183c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar    @Test
2193c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar    fun testFindPublisher() {
2203c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar        simpleRun(jfos = *arrayOf(COMMON.PUBLISHER, COMMON.FLOWABLE, COMMON.RX2_ROOM)) {
2213c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar            invocation ->
2223c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar            val publisher = invocation.processingEnv.elementUtils
2233c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar                    .getTypeElement(ReactiveStreamsTypeNames.PUBLISHER.toString())
2243c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar            assertThat(publisher, notNullValue())
2259fd8e6171bbdc37f5516fe15b2d96f4ae926ef1aChris Craik            assertThat(FlowableQueryResultBinderProvider(invocation.context).matches(
2263c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar                    MoreTypes.asDeclared(publisher.asType())), `is`(true))
2273c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar        }.compilesWithoutError()
2283c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar    }
2293c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar
2303c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar    @Test
2313c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar    fun testFindFlowable() {
2323c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar        simpleRun(jfos = *arrayOf(COMMON.PUBLISHER, COMMON.FLOWABLE, COMMON.RX2_ROOM)) {
2333c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar            invocation ->
2343c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar            val flowable = invocation.processingEnv.elementUtils
2353c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar                    .getTypeElement(RxJava2TypeNames.FLOWABLE.toString())
2363c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar            assertThat(flowable, notNullValue())
2379fd8e6171bbdc37f5516fe15b2d96f4ae926ef1aChris Craik            assertThat(FlowableQueryResultBinderProvider(invocation.context).matches(
2383c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar                    MoreTypes.asDeclared(flowable.asType())), `is`(true))
2393c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar        }.compilesWithoutError()
2403c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar    }
2413c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar
2423c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar    @Test
2433c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar    fun testFindLiveData() {
2443c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar        simpleRun(jfos = *arrayOf(COMMON.COMPUTABLE_LIVE_DATA, COMMON.LIVE_DATA)) {
2453c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar            invocation ->
2463c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar            val liveData = invocation.processingEnv.elementUtils
2473c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar                    .getTypeElement(LifecyclesTypeNames.LIVE_DATA.toString())
2483c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar            assertThat(liveData, notNullValue())
2499fd8e6171bbdc37f5516fe15b2d96f4ae926ef1aChris Craik            assertThat(LiveDataQueryResultBinderProvider(invocation.context).matches(
2503c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar                    MoreTypes.asDeclared(liveData.asType())), `is`(true))
2513c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar        }.compilesWithoutError()
2523c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar    }
2533c592c4ccbc6052b11443b0fa575052c08fefa55Yigit Boyar
2549fd8e6171bbdc37f5516fe15b2d96f4ae926ef1aChris Craik    @Test
255abd098954d3fe996f336201ccb25884aaa34e07fYigit Boyar    fun findDataSource() {
2569fd8e6171bbdc37f5516fe15b2d96f4ae926ef1aChris Craik        simpleRun {
2579fd8e6171bbdc37f5516fe15b2d96f4ae926ef1aChris Craik            invocation ->
25824418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik            val dataSource = invocation.processingEnv.elementUtils
25924418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik                    .getTypeElement(DataSource::class.java.canonicalName)
26024418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik            assertThat(dataSource, notNullValue())
26124418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik            assertThat(DataSourceQueryResultBinderProvider(invocation.context).matches(
262abd098954d3fe996f336201ccb25884aaa34e07fYigit Boyar                    MoreTypes.asDeclared(dataSource.asType())), `is`(true))
263abd098954d3fe996f336201ccb25884aaa34e07fYigit Boyar        }.failsToCompile().withErrorContaining(ProcessorErrors.PAGING_SPECIFY_DATA_SOURCE_TYPE)
264abd098954d3fe996f336201ccb25884aaa34e07fYigit Boyar    }
265abd098954d3fe996f336201ccb25884aaa34e07fYigit Boyar
266abd098954d3fe996f336201ccb25884aaa34e07fYigit Boyar    @Test
267abd098954d3fe996f336201ccb25884aaa34e07fYigit Boyar    fun findTiledDataSource() {
268abd098954d3fe996f336201ccb25884aaa34e07fYigit Boyar        simpleRun {
269abd098954d3fe996f336201ccb25884aaa34e07fYigit Boyar            invocation ->
270abd098954d3fe996f336201ccb25884aaa34e07fYigit Boyar            val dataSource = invocation.processingEnv.elementUtils
271abd098954d3fe996f336201ccb25884aaa34e07fYigit Boyar                    .getTypeElement(TiledDataSource::class.java.canonicalName)
272abd098954d3fe996f336201ccb25884aaa34e07fYigit Boyar            assertThat(dataSource, notNullValue())
273abd098954d3fe996f336201ccb25884aaa34e07fYigit Boyar            assertThat(DataSourceQueryResultBinderProvider(invocation.context).matches(
27424418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik                    MoreTypes.asDeclared(dataSource.asType())), `is`(true))
2759fd8e6171bbdc37f5516fe15b2d96f4ae926ef1aChris Craik        }.compilesWithoutError()
2769fd8e6171bbdc37f5516fe15b2d96f4ae926ef1aChris Craik    }
2779fd8e6171bbdc37f5516fe15b2d96f4ae926ef1aChris Craik
2789fd8e6171bbdc37f5516fe15b2d96f4ae926ef1aChris Craik    @Test
27924418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik    fun findPagedListProvider() {
28024418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik        simpleRun(jfos = COMMON.LIVE_PAGED_LIST_PROVIDER) {
2819fd8e6171bbdc37f5516fe15b2d96f4ae926ef1aChris Craik            invocation ->
28224418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik            val pagedListProvider = invocation.processingEnv.elementUtils
28324418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik                    .getTypeElement(PagingTypeNames.LIVE_PAGED_LIST_PROVIDER.toString())
28424418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik            assertThat(pagedListProvider, notNullValue())
28524418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik            assertThat(LivePagedListQueryResultBinderProvider(invocation.context).matches(
28624418e9aafa6ae3128ae47cf7087eda46dae4f5dChris Craik                    MoreTypes.asDeclared(pagedListProvider.asType())), `is`(true))
2879fd8e6171bbdc37f5516fe15b2d96f4ae926ef1aChris Craik        }.compilesWithoutError()
2889fd8e6171bbdc37f5516fe15b2d96f4ae926ef1aChris Craik    }
2899fd8e6171bbdc37f5516fe15b2d96f4ae926ef1aChris Craik
290fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar    private fun createIntListToStringBinders(invocation: TestInvocation): List<TypeConverter> {
291fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar        val intType = invocation.processingEnv.elementUtils
292fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar                .getTypeElement(Integer::class.java.canonicalName)
293fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar                .asType()
294fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar        val listType = invocation.processingEnv.elementUtils
295fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar                .getTypeElement(java.util.List::class.java.canonicalName)
296fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar        val listOfInts = invocation.processingEnv.typeUtils.getDeclaredType(listType, intType)
297fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar
298fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar        val intListConverter = object : TypeConverter(listOfInts,
299fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar                invocation.context.COMMON_TYPES.STRING) {
300fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar            override fun convert(inputVarName: String, outputVarName: String,
301fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar                                 scope: CodeGenScope) {
302fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar                scope.builder().apply {
303fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar                    addStatement("$L = $T.joinIntoString($L)", outputVarName, STRING_UTIL,
304fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar                            inputVarName)
305fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar                }
306fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar            }
307fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar        }
308fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar
309fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar        val stringToIntListConverter = object : TypeConverter(
310fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar                invocation.context.COMMON_TYPES.STRING, listOfInts) {
311fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar            override fun convert(inputVarName: String, outputVarName: String,
312fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar                                 scope: CodeGenScope) {
313fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar                scope.builder().apply {
314fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar                    addStatement("$L = $T.splitToIntList($L)", outputVarName, STRING_UTIL,
315fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar                            inputVarName)
316fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar                }
317fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar            }
318fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar        }
319fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar        return listOf(intListConverter, stringToIntListConverter)
320fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar    }
321fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar
3222259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar    fun singleRun(handler: (TestInvocation) -> Unit): CompileTester {
3232259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar        return Truth.assertAbout(JavaSourcesSubjectFactory.javaSources())
3242259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar                .that(listOf(JavaFileObjects.forSourceString("foo.bar.DummyClass",
3252259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar                        """
3262259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar                        package foo.bar;
32764db0cc15b78b62a1d44a70fc8b4552e660d952cYigit Boyar                        import android.arch.persistence.room.*;
3282259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar                        @Entity
3292259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar                        public class DummyClass {}
3302259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar                        """
3312259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar                ), JavaFileObjects.forSourceString("foo.bar.Point",
3322259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar                        """
3332259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar                        package foo.bar;
33464db0cc15b78b62a1d44a70fc8b4552e660d952cYigit Boyar                        import android.arch.persistence.room.*;
3352259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar                        @Entity
3362259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar                        public class Point {
3372259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar                            public int x, y;
3382259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar                            public Point(int x, int y) {
3392259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar                                this.x = x;
3402259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar                                this.y = y;
3412259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar                            }
3422259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar                            public static Point fromBoolean(boolean val) {
3432259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar                                return val ? new Point(1, 1) : new Point(0, 0);
3442259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar                            }
3452259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar                            public static boolean toBoolean(Point point) {
3462259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar                                return point.x > 0;
3472259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar                            }
3482259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar                        }
3492259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar                        """
3502259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar                )))
3512259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar                .processedWith(TestProcessor.builder()
3522259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar                        .forAnnotations(Entity::class)
3532259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar                        .nextRunHandler { invocation ->
3542259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar                            handler(invocation)
3552259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar                            true
3562259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar                        }
3572259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar                        .build())
3582259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar    }
3592259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar
360fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar    fun pointTypeConverters(env: ProcessingEnvironment): List<TypeConverter> {
361fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar        val tPoint = env.elementUtils.getTypeElement("foo.bar.Point").asType()
362fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar        val tBoolean = env.typeUtils.getPrimitiveType(TypeKind.BOOLEAN)
363fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar        return listOf(
364fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar                object : TypeConverter(tPoint, tBoolean) {
365fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar                    override fun convert(inputVarName: String, outputVarName: String,
366fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar                                         scope: CodeGenScope) {
367fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar                        scope.builder().apply {
368fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar                            addStatement("$L = $T.toBoolean($L)", outputVarName, from, inputVarName)
369fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar                        }
370fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar                    }
3712259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar
372fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar                },
373fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar                object : TypeConverter(tBoolean, tPoint) {
374fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar                    override fun convert(inputVarName: String, outputVarName: String,
375fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar                                         scope: CodeGenScope) {
376fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar                        scope.builder().apply {
377fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar                            addStatement("$L = $T.fromBoolean($L)", outputVarName, tPoint,
378fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar                                    inputVarName)
379fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar                        }
380fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar                    }
381fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar                }
382fb4fcc8caf2a1908843bd18298447ff6fc498896Yigit Boyar        )
3832259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar    }
3841676c28584028f8427475745d7a779607af67ecbYigit Boyar
3851676c28584028f8427475745d7a779607af67ecbYigit Boyar    fun dateTypeConverters(env: ProcessingEnvironment): List<TypeConverter> {
3861676c28584028f8427475745d7a779607af67ecbYigit Boyar        val tDate = env.elementUtils.getTypeElement("java.util.Date").asType()
3871676c28584028f8427475745d7a779607af67ecbYigit Boyar        val tLong = env.elementUtils.getTypeElement("java.lang.Long").asType()
3881676c28584028f8427475745d7a779607af67ecbYigit Boyar        return listOf(
3891676c28584028f8427475745d7a779607af67ecbYigit Boyar                object : TypeConverter(tDate, tLong) {
3901676c28584028f8427475745d7a779607af67ecbYigit Boyar                    override fun convert(inputVarName: String, outputVarName: String,
3911676c28584028f8427475745d7a779607af67ecbYigit Boyar                                         scope: CodeGenScope) {
3921676c28584028f8427475745d7a779607af67ecbYigit Boyar                        scope.builder().apply {
3931676c28584028f8427475745d7a779607af67ecbYigit Boyar                            addStatement("// convert Date to Long")
3941676c28584028f8427475745d7a779607af67ecbYigit Boyar                        }
3951676c28584028f8427475745d7a779607af67ecbYigit Boyar                    }
3961676c28584028f8427475745d7a779607af67ecbYigit Boyar
3971676c28584028f8427475745d7a779607af67ecbYigit Boyar                },
3981676c28584028f8427475745d7a779607af67ecbYigit Boyar                object : TypeConverter(tLong, tDate) {
3991676c28584028f8427475745d7a779607af67ecbYigit Boyar                    override fun convert(inputVarName: String, outputVarName: String,
4001676c28584028f8427475745d7a779607af67ecbYigit Boyar                                         scope: CodeGenScope) {
4011676c28584028f8427475745d7a779607af67ecbYigit Boyar                        scope.builder().apply {
4021676c28584028f8427475745d7a779607af67ecbYigit Boyar                            addStatement("// convert Long to Date")
4031676c28584028f8427475745d7a779607af67ecbYigit Boyar                        }
4041676c28584028f8427475745d7a779607af67ecbYigit Boyar                    }
4051676c28584028f8427475745d7a779607af67ecbYigit Boyar                }
4061676c28584028f8427475745d7a779607af67ecbYigit Boyar        )
4071676c28584028f8427475745d7a779607af67ecbYigit Boyar    }
4082259e4dc433701d006db35df4c5e9f8d51e7d29bYigit Boyar}
409