Support internal properties in Room

This CL fixes a bug in POJO processor where while matching fields to
methods, it was using the jvm name of the method rather than the source
name.

As the JVM name for internal properties get a $pkg suffix, they were not
matching the property

Fixes: 205289020
Test: InternalsTest
RelNote: "Added support for internal properties in Kotlin sources.
This is a slight behavior change in Room where it will use the source
name of functions while matching them to properties as getters/setters
(previously, it was using JVM name of the function which is different
for internal functions/properties).
If you are using custom `@JvmName` annotations to match getters/setters
to private properties, please double check the generated code after the
update"
Change-Id: If653164362c49fd00650d9a953f330afdb309c1c
(cherry picked from commit 7ce58f6d42595983aab61f37ac70032e9171e238)
Merged-In:If653164362c49fd00650d9a953f330afdb309c1c
diff --git a/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/InternalsTest.kt b/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/InternalsTest.kt
new file mode 100644
index 0000000..e5f90ed
--- /dev/null
+++ b/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/InternalsTest.kt
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2021 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.androidx.room.integration.kotlintestapp.test
+
+import androidx.room.Dao
+import androidx.room.Database
+import androidx.room.Entity
+import androidx.room.Insert
+import androidx.room.PrimaryKey
+import androidx.room.Query
+import androidx.room.Room
+import androidx.room.RoomDatabase
+import androidx.test.filters.SmallTest
+import androidx.test.platform.app.InstrumentationRegistry
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+
+/**
+ * Test to make sure we can generate proper code when developer uses internals hence
+ * jvm names might be different than what developer sees
+ */
+@SmallTest
+class InternalsTest {
+    @Database(
+        version = 1,
+        entities = [InternalEntity::class],
+        exportSchema = false
+    )
+    internal abstract class InternalDb : RoomDatabase() {
+        abstract val dao: InternalDao
+    }
+
+    @Entity
+    internal class InternalEntity(
+        @PrimaryKey
+        internal val id: Long,
+        internal val internalField: String,
+        val publicField: String
+    ) {
+        // these are added to have setters
+        internal var internalFieldProp: String = ""
+        var publicFieldProp: String = ""
+        override fun equals(other: Any?): Boolean {
+            if (this === other) return true
+            if (other !is InternalEntity) return false
+            if (id != other.id) return false
+            if (internalField != other.internalField) return false
+            if (publicField != other.publicField) return false
+            if (internalFieldProp != other.internalFieldProp) return false
+            if (publicFieldProp != other.publicFieldProp) return false
+            return true
+        }
+
+        override fun hashCode(): Int {
+            var result = id.hashCode()
+            result = 31 * result + internalField.hashCode()
+            result = 31 * result + publicField.hashCode()
+            result = 31 * result + internalFieldProp.hashCode()
+            result = 31 * result + publicFieldProp.hashCode()
+            return result
+        }
+    }
+
+    @Dao
+    internal abstract class InternalDao {
+        @Insert
+        abstract fun insert(entity: InternalEntity)
+
+        @Query("SELECT * FROM InternalEntity WHERE publicField LIKE :field")
+        abstract fun byPublicField(field: String): List<InternalEntity>
+
+        @Query("SELECT * FROM InternalEntity WHERE internalField LIKE :field")
+        abstract fun byInternalField(field: String): List<InternalEntity>
+
+        @Query("SELECT * FROM InternalEntity WHERE publicFieldProp LIKE :field")
+        abstract fun byPublicFieldProp(field: String): List<InternalEntity>
+
+        @Query("SELECT * FROM InternalEntity WHERE internalFieldProp LIKE :field")
+        abstract fun byInternalFieldProp(field: String): List<InternalEntity>
+    }
+
+    private lateinit var db: InternalDb
+
+    @Before
+    fun init() {
+        db = Room.inMemoryDatabaseBuilder(
+            InstrumentationRegistry.getInstrumentation().context,
+            InternalDb::class.java
+        ).build()
+    }
+
+    @Test
+    fun test() {
+        val entity = InternalEntity(
+            id = 1,
+            internalField = "if",
+            publicField = "pf"
+        ).also {
+            it.internalFieldProp = "ifp"
+            it.publicFieldProp = "pfp"
+        }
+        db.dao.insert(entity)
+        assertThat(
+            db.dao.byInternalField(field = "if")
+        ).containsExactly(entity)
+        assertThat(
+            db.dao.byPublicField(field = "pf")
+        ).containsExactly(entity)
+        assertThat(
+            db.dao.byInternalFieldProp(field = "ifp")
+        ).containsExactly(entity)
+        assertThat(
+            db.dao.byPublicFieldProp(field = "pfp")
+        ).containsExactly(entity)
+    }
+}
diff --git a/room/room-compiler/src/main/kotlin/androidx/room/processor/PojoProcessor.kt b/room/room-compiler/src/main/kotlin/androidx/room/processor/PojoProcessor.kt
index 5943caa..30f1f9c 100644
--- a/room/room-compiler/src/main/kotlin/androidx/room/processor/PojoProcessor.kt
+++ b/room/room-compiler/src/main/kotlin/androidx/room/processor/PojoProcessor.kt
@@ -881,10 +881,12 @@
         val matching = candidates
             .filter {
                 // b/69164099
+                // use names in source (rather than jvmName) for matching since that is what user
+                // sees in code
                 field.type.isAssignableFromWithoutVariance(getType(it)) &&
                     (
-                        field.nameWithVariations.contains(it.element.jvmName) ||
-                            nameVariations.contains(it.element.jvmName)
+                        field.nameWithVariations.contains(it.element.name) ||
+                            nameVariations.contains(it.element.name)
                         )
             }
             .groupBy {
@@ -917,7 +919,7 @@
             return null
         }
         if (candidates.size > 1) {
-            reportAmbiguity(candidates.map { it.element.jvmName })
+            reportAmbiguity(candidates.map { it.element.name })
         }
         return candidates.first()
     }