Update KSP to 20201120

I've also updated KSP implementation to treat internals as KAPT.
This means, any method that receives or returns inline is hidden.

Method / property names are now read from KSP which properly modifies
them to have their jvm names applies (including internals).

Unfortunately, this hits a bug in KSP. I've safe guarded it for now
only where it reproduces to avoid hiding possible other places where
it might occur.
https://github.com/google/ksp/issues/164

Bug: 160322705
Test: InternalModifierTest
Change-Id: I739de215f40a453f4ddfb82290c969e0478de471
diff --git a/buildSrc/src/main/kotlin/androidx/build/dependencies/Dependencies.kt b/buildSrc/src/main/kotlin/androidx/build/dependencies/Dependencies.kt
index 50f90376..02db235 100644
--- a/buildSrc/src/main/kotlin/androidx/build/dependencies/Dependencies.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/dependencies/Dependencies.kt
@@ -77,7 +77,7 @@
     "com.squareup:kotlinpoet-classinspector-elements:1.4.0"
 const val KOTLIN_COMPILE_TESTING = "com.github.tschuchortdev:kotlin-compile-testing:1.3.1"
 const val KOTLIN_COMPILE_TESTING_KSP = "com.github.tschuchortdev:kotlin-compile-testing-ksp:1.3.1"
-const val KSP_VERSION = "1.4.10-dev-experimental-20201110"
+const val KSP_VERSION = "1.4.10-dev-experimental-20201120"
 const val KOTLIN_KSP_API = "com.google.devtools.ksp:symbol-processing-api:$KSP_VERSION"
 const val KOTLIN_KSP = "com.google.devtools.ksp:symbol-processing:$KSP_VERSION"
 const val KOTLIN_GRADLE_PLUGIN = "org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.20"
diff --git a/room/compiler-processing/build.gradle b/room/compiler-processing/build.gradle
index 8f3616f..795a691 100644
--- a/room/compiler-processing/build.gradle
+++ b/room/compiler-processing/build.gradle
@@ -16,6 +16,7 @@
 
 import androidx.build.LibraryGroups
 import androidx.build.LibraryType
+import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
 
 import static androidx.build.dependencies.DependenciesKt.*
 
@@ -56,11 +57,13 @@
     testImplementation(project(":room:room-compiler-processing-testing"))
 }
 
-compileKotlin {
+tasks.withType(KotlinCompile).configureEach {
     kotlinOptions {
-        freeCompilerArgs += "-Xopt-in=kotlin.contracts.ExperimentalContracts"
+        freeCompilerArgs += ["-Xopt-in=kotlin.RequiresOptIn",
+                             "-Xopt-in=kotlin.contracts.ExperimentalContracts"]
     }
 }
+
 androidx {
     name = "AndroidX Room XProcessor"
     type = LibraryType.ANNOTATION_PROCESSOR
diff --git a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KSTypeExt.kt b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KSTypeExt.kt
index 61e7271..31b2ad9 100644
--- a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KSTypeExt.kt
+++ b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KSTypeExt.kt
@@ -18,6 +18,7 @@
 
 import androidx.room.compiler.processing.javac.kotlin.typeNameFromJvmSignature
 import androidx.room.compiler.processing.tryBox
+import com.google.devtools.ksp.KspExperimental
 import com.google.devtools.ksp.processing.Resolver
 import com.squareup.javapoet.ClassName
 import com.squareup.javapoet.ParameterizedTypeName
@@ -29,6 +30,7 @@
 import com.google.devtools.ksp.symbol.KSTypeArgument
 import com.google.devtools.ksp.symbol.KSTypeParameter
 import com.google.devtools.ksp.symbol.KSTypeReference
+import com.google.devtools.ksp.symbol.Modifier
 import com.google.devtools.ksp.symbol.Variance
 import com.squareup.javapoet.ArrayTypeName
 
@@ -51,6 +53,7 @@
 /**
  * Turns a KSDeclaration into a TypeName in java's type system.
  */
+@OptIn(KspExperimental::class)
 internal fun KSDeclaration.typeName(resolver: Resolver): TypeName {
     // if there is no qualified name, it is a resolution error so just return shared instance
     // KSP may improve that later and if not, we can improve it in Room
@@ -147,4 +150,6 @@
 
 internal fun KSTypeReference.isTypeParameterReference(): Boolean {
     return this.resolve().declaration is KSTypeParameter
-}
\ No newline at end of file
+}
+
+fun KSType.isInline() = declaration.modifiers.contains(Modifier.INLINE)
\ No newline at end of file
diff --git a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspFieldElement.kt b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspFieldElement.kt
index 8f8e32d..90f46c7 100644
--- a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspFieldElement.kt
+++ b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspFieldElement.kt
@@ -46,7 +46,7 @@
         declaration.simpleName.asString()
     }
 
-    override val type: XType by lazy {
+    override val type: KspType by lazy {
         env.wrap(
             originatingReference = declaration.type,
             ksType = declaration.typeAsMemberOf(env.resolver, containing.type.ksType)
diff --git a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspMethodElement.kt b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspMethodElement.kt
index c88abf7..48841e32 100644
--- a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspMethodElement.kt
+++ b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspMethodElement.kt
@@ -23,6 +23,7 @@
 import androidx.room.compiler.processing.XType
 import androidx.room.compiler.processing.XTypeElement
 import androidx.room.compiler.processing.ksp.synthetic.KspSyntheticContinuationParameterElement
+import com.google.devtools.ksp.KspExperimental
 import com.google.devtools.ksp.symbol.ClassKind
 import com.google.devtools.ksp.symbol.KSClassDeclaration
 import com.google.devtools.ksp.symbol.KSFunctionDeclaration
@@ -39,8 +40,15 @@
 ),
     XMethodElement {
 
+    @OptIn(KspExperimental::class)
     override val name: String by lazy {
-        declaration.simpleName.asString()
+        try {
+            env.resolver.getJvmName(declaration)
+        } catch (ignored: ClassCastException) {
+            // TODO remove this catch once that issue is fixed.
+            // workaround for https://github.com/google/ksp/issues/164
+            declaration.simpleName.asString()
+        }
     }
 
     override val executableType: XMethodType by lazy {
diff --git a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspTypeElement.kt b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspTypeElement.kt
index f4575aa..eb88523 100644
--- a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspTypeElement.kt
+++ b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspTypeElement.kt
@@ -147,6 +147,11 @@
 
     private val syntheticGetterSetterMethods: List<XMethodElement> by lazy {
         val setters = _declaredPropertyFields.mapNotNull {
+            if (it.type.ksType.isInline()) {
+                // KAPT does not generate getters/setters for inlines, we'll hide them as well
+                // until room generates kotlin code
+                return@mapNotNull null
+            }
             val setter = it.declaration.setter
             val needsSetter = if (setter != null) {
                 // kapt does not generate synthetics for private fields/setters so we won't either
@@ -164,6 +169,11 @@
             }
         }
         val getters = _declaredPropertyFields.mapNotNull {
+            if (it.type.ksType.isInline()) {
+                // KAPT does not generate getters/setters for inlines, we'll hide them as well
+                // until room generates kotlin code
+                return@mapNotNull null
+            }
             val getter = it.declaration.getter
             val needsGetter = if (getter != null) {
                 // kapt does not generate synthetics for private fields/getters so we won't either]
@@ -211,17 +221,23 @@
     }
 
     private val _declaredMethods by lazy {
-        val myMethods = declaration.getDeclaredFunctions()
-            .filter {
+        val myMethods = declaration.getDeclaredFunctions().asSequence()
+            .filterNot {
                 // filter out constructors
-                it.simpleName.asString() != name
+                it.simpleName.asString() == name
+            }.filterNot {
+                // if it receives or returns inline, drop it.
+                // we can re-enable these once room generates kotlin code
+                it.parameters.any {
+                    it.type.resolve().isInline()
+                } || it.returnType?.resolve()?.isInline() == true
             }.map {
                 KspMethodElement.create(
                     env = env,
                     containing = this,
                     declaration = it
                 )
-            }
+            }.toList()
         val companionMethods = declaration.findCompanionObject()
             ?.let {
                 env.wrapClassDeclaration(it)
diff --git a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/synthetic/KspSyntheticPropertyMethodElement.kt b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/synthetic/KspSyntheticPropertyMethodElement.kt
index a6c4e46..868a69c 100644
--- a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/synthetic/KspSyntheticPropertyMethodElement.kt
+++ b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/synthetic/KspSyntheticPropertyMethodElement.kt
@@ -35,6 +35,7 @@
 import androidx.room.compiler.processing.ksp.KspProcessingEnv
 import androidx.room.compiler.processing.ksp.KspTypeElement
 import androidx.room.compiler.processing.ksp.overrides
+import com.google.devtools.ksp.KspExperimental
 import com.google.devtools.ksp.symbol.KSPropertyAccessor
 import java.util.Locale
 
@@ -117,7 +118,11 @@
             arrayOf(field, "getter")
         }
 
+        @OptIn(KspExperimental::class)
         override val name: String by lazy {
+            field.declaration.getter?.let {
+                return@lazy env.resolver.getJvmName(it)
+            }
             // see https://kotlinlang.org/docs/reference/java-to-kotlin-interop.html#properties
             val propName = field.name
             if (propName.startsWith("is")) {
@@ -168,7 +173,11 @@
             arrayOf(field, "setter")
         }
 
+        @OptIn(KspExperimental::class)
         override val name: String by lazy {
+            field.declaration.setter?.let {
+                return@lazy env.resolver.getJvmName(it)
+            }
             // see https://kotlinlang.org/docs/reference/java-to-kotlin-interop.html#properties
             val propName = field.name
             if (propName.startsWith("is")) {
diff --git a/room/compiler-processing/src/test/java/androidx/room/compiler/processing/InternalModifierTest.kt b/room/compiler-processing/src/test/java/androidx/room/compiler/processing/InternalModifierTest.kt
new file mode 100644
index 0000000..f604802
--- /dev/null
+++ b/room/compiler-processing/src/test/java/androidx/room/compiler/processing/InternalModifierTest.kt
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2020 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.processing
+
+import androidx.room.compiler.processing.util.Source
+import androidx.room.compiler.processing.util.runKaptTest
+import androidx.room.compiler.processing.util.runKspTest
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+
+class InternalModifierTest {
+    @OptIn(ExperimentalStdlibApi::class)
+    @Test
+    fun testInternalsAndInlines() {
+        /**
+         * parse same file w/ kapt and KSP and ensure results are the same.
+         */
+        val source = Source.kotlin(
+            "Subject.kt",
+            """
+            package mainPackage;
+            internal class InternalClass(val value: String)
+            inline class InlineClass(val value:String)
+            class Subject {
+                var normalProp: String = TODO()
+                var inlineProp: InlineClass = TODO()
+                internal var internalProp: String = TODO()
+                internal var internalInlineProp: InlineClass = TODO()
+                private var internalTypeProp : InternalClass = TODO()
+                @get:JvmName("explicitGetterName")
+                @set:JvmName("explicitSetterName")
+                var jvmNameProp:String
+                fun normalFun() {}
+                @JvmName("explicitJvmName")
+                fun hasJvmName() {}
+                fun inlineReceivingFun(value: InlineClass) {}
+                fun inlineReturningFun(): InlineClass = TODO()
+                internal fun internalInlineReceivingFun(value: InlineClass) {}
+                internal fun internalInlineReturningFun(): InlineClass = TODO()
+                inline fun inlineFun() {
+                    TODO()
+                }
+            }
+            """.trimIndent()
+        )
+
+        fun XType.toSignature() = this.typeName.toString()
+
+        fun XFieldElement.toSignature() = "$name : ${type.toSignature()}"
+
+        fun XMethodElement.toSignature() = buildString {
+            append(name)
+            append("(")
+            parameters.forEach {
+                append(it.type.toSignature())
+            }
+            append(")")
+            append(":")
+            append(returnType.toSignature())
+        }
+
+        fun traverse(env: XProcessingEnv) = buildList<String> {
+            val subject = env.requireTypeElement("mainPackage.Subject")
+            add(subject.name)
+            add(subject.qualifiedName)
+            subject.getDeclaredMethods().forEach {
+                add(it.toSignature())
+            }
+            subject.getAllFieldsIncludingPrivateSupers().map {
+                add(it.toSignature())
+            }
+        }.sorted().joinToString("\n")
+
+        var kaptResult: String = "pending"
+        var kspResult: String = "pending"
+        runKaptTest(
+            sources = listOf(source)
+        ) { invocation ->
+            kaptResult = traverse(invocation.processingEnv)
+        }
+
+        runKspTest(
+            sources = listOf(source)
+        ) { invocation ->
+            kspResult = traverse(invocation.processingEnv)
+        }
+
+        assertThat(kspResult).isEqualTo(kaptResult)
+    }
+}
\ No newline at end of file