[go: nahoru, domu]

resolve Coastguard cherrypick merge conflict for change: 2154273

Change-Id: I48194068e85d5862a831dbc992c8aa1c1a703769
(cherry picked from commit f7247ba3618d4761efcf3a584bba61e018fdabad)
Merged-In: I48194068e85d5862a831dbc992c8aa1c1a703769
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/DeclarationCollector.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/DeclarationCollector.kt
index f0027c5..5867045 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/DeclarationCollector.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/DeclarationCollector.kt
@@ -36,7 +36,7 @@
                 }
             }
             // visit all declared fields on super types
-            type.superType?.typeElement?.let { parent ->
+            type.superClass?.typeElement?.let { parent ->
                 yieldAllFields(parent)
             }
         }
@@ -66,7 +66,7 @@
                 }
             }
             // Next, visit all super class methods.
-            type.superType?.typeElement?.let {
+            type.superClass?.typeElement?.let {
                 collectAllMethodsByName(it)
             }
             // Finally, visit all methods declared in this type.
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/XTypeElement.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/XTypeElement.kt
index 5aef173..9044c15 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/XTypeElement.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/XTypeElement.kt
@@ -44,7 +44,24 @@
     /**
      * The super type of this element if it represents a class.
      */
+    @Deprecated(
+        message = "Function name was misleading.",
+        replaceWith = ReplaceWith("superClass")
+    )
     val superType: XType?
+        get() = superClass
+
+    /**
+     * The direct super types of this element.
+     *
+     * See [JLS 4.10.2](https://docs.oracle.com/javase/specs/jls/se18/html/jls-4.html#jls-4.10.2)
+     */
+    val superTypes: List<XType>
+
+    /**
+     * The super class of this element if it represents a class.
+     */
+    val superClass: XType?
 
     /**
      * The super interfaces implemented by this class.
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacTypeElement.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacTypeElement.kt
index 5d319c9..a03b660 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacTypeElement.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacTypeElement.kt
@@ -21,6 +21,7 @@
 import androidx.room.compiler.processing.XFieldElement
 import androidx.room.compiler.processing.XHasModifiers
 import androidx.room.compiler.processing.XMethodElement
+import androidx.room.compiler.processing.XType
 import androidx.room.compiler.processing.XTypeElement
 import androidx.room.compiler.processing.collectAllMethods
 import androidx.room.compiler.processing.collectFieldsIncludingPrivateSupers
@@ -30,6 +31,7 @@
 import com.google.auto.common.MoreElements
 import com.google.auto.common.MoreTypes
 import com.squareup.javapoet.ClassName
+import com.squareup.javapoet.TypeName
 import javax.lang.model.element.ElementKind
 import javax.lang.model.element.TypeElement
 import javax.lang.model.type.TypeKind
@@ -166,7 +168,18 @@
         )
     }
 
-    override val superType: JavacType? by lazy {
+    override val superTypes: List<XType> by lazy {
+        buildList {
+            if (isInterface() && superInterfaces.isEmpty()) {
+                add(env.requireType(TypeName.OBJECT))
+            } else {
+                superClass?.let { add(it) }
+                addAll(superInterfaces)
+            }
+        }
+    }
+
+    override val superClass: JavacType? by lazy {
         // javac models non-existing types as TypeKind.NONE but we prefer to make it nullable.
         // just makes more sense and safer as we don't need to check for none.
 
diff --git a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspTypeElement.kt b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspTypeElement.kt
index d75756f..eef811f 100644
--- a/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspTypeElement.kt
+++ b/room/room-compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspTypeElement.kt
@@ -41,6 +41,7 @@
 import com.google.devtools.ksp.symbol.KSPropertyDeclaration
 import com.google.devtools.ksp.symbol.Modifier
 import com.squareup.javapoet.ClassName
+import com.squareup.javapoet.TypeName
 
 internal sealed class KspTypeElement(
     env: KspProcessingEnv,
@@ -79,15 +80,32 @@
         )
     }
 
-    override val superType: XType? by lazy {
-        declaration.superTypes.firstOrNull {
-            val type = it.resolve().declaration as? KSClassDeclaration ?: return@firstOrNull false
-            type.classKind == ClassKind.CLASS
-        }?.let {
-            env.wrap(
-                ksType = it.resolve(),
-                allowPrimitives = false
-            )
+    override val superTypes: List<XType> by lazy {
+        buildList {
+            if (isInterface() && superInterfaces.isEmpty()) {
+                add(env.requireType(TypeName.OBJECT))
+            } else {
+                superClass?.let { add(it) }
+                addAll(superInterfaces)
+            }
+        }
+    }
+
+    override val superClass: XType? by lazy {
+        if (isInterface()) {
+            // interfaces don't have super classes (they do have super types)
+            null
+        } else {
+            declaration.superTypes.firstOrNull {
+                val type =
+                    it.resolve().declaration as? KSClassDeclaration ?: return@firstOrNull false
+                type.classKind == ClassKind.CLASS
+            }?.let {
+                env.wrap(
+                    ksType = it.resolve(),
+                    allowPrimitives = false
+                )
+            }
         }
     }
 
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XElementTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XElementTest.kt
index 2508281..2035a8a 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XElementTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XElementTest.kt
@@ -457,7 +457,7 @@
         ) {
             val element = it.processingEnv.requireTypeElement("java.lang.Object")
             // make sure we return null for not existing types
-            assertThat(element.superType).isNull()
+            assertThat(element.superClass).isNull()
         }
     }
 
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XProcessingEnvTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XProcessingEnvTest.kt
index 5e567bb..a66452a 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XProcessingEnvTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XProcessingEnvTest.kt
@@ -123,7 +123,7 @@
             assertThat(element.getDeclaredMethods()).hasSize(2)
             assertThat(element.kindName()).isEqualTo("class")
             assertThat(element.isInterface()).isFalse()
-            assertThat(element.superType?.typeName).isEqualTo(TypeName.OBJECT)
+            assertThat(element.superClass?.typeName).isEqualTo(TypeName.OBJECT)
         }
     }
 
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XTypeElementTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XTypeElementTest.kt
index 5970140..3c4ad85 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XTypeElementTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XTypeElementTest.kt
@@ -118,13 +118,18 @@
             }
             abstract class AbstractClass {}
             interface MyInterface {}
+            interface AnotherInterface : MyInterface {}
             """.trimIndent()
         )
         runProcessorTest(sources = listOf(src)) { invocation ->
             invocation.processingEnv.requireTypeElement("foo.bar.Baz").let {
-                assertThat(it.superType).isEqualTo(
+                assertThat(it.superClass).isEqualTo(
                     invocation.processingEnv.requireType("foo.bar.AbstractClass")
                 )
+                assertThat(it.superTypes).containsExactly(
+                    invocation.processingEnv.requireType("foo.bar.AbstractClass"),
+                    invocation.processingEnv.requireType("foo.bar.MyInterface")
+                )
                 assertThat(it.type).isEqualTo(
                     invocation.processingEnv.requireType("foo.bar.Baz")
                 )
@@ -133,16 +138,12 @@
                 assertThat(it.isAbstract()).isFalse()
             }
             invocation.processingEnv.requireTypeElement("foo.bar.AbstractClass").let {
-                assertThat(it.superType).let {
-                    // KSP does not return Object / Any as super class
-                    if (invocation.isKsp) {
-                        it.isNull()
-                    } else {
-                        it.isEqualTo(
-                            invocation.processingEnv.requireType(TypeName.OBJECT)
-                        )
-                    }
-                }
+                assertThat(it.superClass).isEqualTo(
+                    invocation.processingEnv.requireType(TypeName.OBJECT)
+                )
+                assertThat(it.superTypes).containsExactly(
+                    invocation.processingEnv.requireType(TypeName.OBJECT)
+                )
                 assertThat(it.isAbstract()).isTrue()
                 assertThat(it.isInterface()).isFalse()
                 assertThat(it.type).isEqualTo(
@@ -150,12 +151,25 @@
                 )
             }
             invocation.processingEnv.requireTypeElement("foo.bar.MyInterface").let {
-                assertThat(it.superType).isNull()
+                assertThat(it.superClass).isNull()
+                assertThat(it.superTypes).containsExactly(
+                    invocation.processingEnv.requireType(TypeName.OBJECT)
+                )
                 assertThat(it.isInterface()).isTrue()
                 assertThat(it.type).isEqualTo(
                     invocation.processingEnv.requireType("foo.bar.MyInterface")
                 )
             }
+            invocation.processingEnv.requireTypeElement("foo.bar.AnotherInterface").let {
+                assertThat(it.superClass).isNull()
+                assertThat(it.superTypes).containsExactly(
+                    invocation.processingEnv.requireType("foo.bar.MyInterface")
+                )
+                assertThat(it.isInterface()).isTrue()
+                assertThat(it.type).isEqualTo(
+                    invocation.processingEnv.requireType("foo.bar.AnotherInterface")
+                )
+            }
         }
     }
 
diff --git a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XTypeTest.kt b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XTypeTest.kt
index e9105f8..9f0364c 100644
--- a/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XTypeTest.kt
+++ b/room/room-compiler-processing/src/test/java/androidx/room/compiler/processing/XTypeTest.kt
@@ -270,7 +270,7 @@
             sources = listOf(missingTypeRef)
         ) {
             val element = it.processingEnv.requireTypeElement("foo.bar.Baz")
-            assertThat(element.superType?.isError()).isTrue()
+            assertThat(element.superClass?.isError()).isTrue()
             it.assertCompilationResult {
                 compilationDidFail()
             }
diff --git a/room/room-compiler/src/main/kotlin/androidx/room/ext/xtype_ext.kt b/room/room-compiler/src/main/kotlin/androidx/room/ext/xtype_ext.kt
index b9e1dd7..315afe6 100644
--- a/room/room-compiler/src/main/kotlin/androidx/room/ext/xtype_ext.kt
+++ b/room/room-compiler/src/main/kotlin/androidx/room/ext/xtype_ext.kt
@@ -95,7 +95,7 @@
 
     if (hasEquals && hasHashCode) return true
 
-    return typeElement.superType?.let { it.implementsEqualsAndHashcode() } ?: false
+    return typeElement.superClass?.implementsEqualsAndHashcode() ?: false
 }
 
 /**
diff --git a/room/room-compiler/src/main/kotlin/androidx/room/processor/DaoProcessor.kt b/room/room-compiler/src/main/kotlin/androidx/room/processor/DaoProcessor.kt
index 0a4a532..7e90b44 100644
--- a/room/room-compiler/src/main/kotlin/androidx/room/processor/DaoProcessor.kt
+++ b/room/room-compiler/src/main/kotlin/androidx/room/processor/DaoProcessor.kt
@@ -172,9 +172,7 @@
         // Kotlin.
         val unannotatedMethods = methods[Any::class] ?: emptyList<XMethodElement>()
         val delegatingMethods =
-            if (element.superType != null ||
-                element.getSuperInterfaceElements().isNotEmpty()
-            ) {
+            if (element.superClass != null || element.getSuperInterfaceElements().isNotEmpty()) {
                 matchKotlinBoxedPrimitiveMethods(
                     unannotatedMethods,
                     methods.values.flatten() - unannotatedMethods
diff --git a/room/room-compiler/src/main/kotlin/androidx/room/processor/TableEntityProcessor.kt b/room/room-compiler/src/main/kotlin/androidx/room/processor/TableEntityProcessor.kt
index 73f549f..1c17c65 100644
--- a/room/room-compiler/src/main/kotlin/androidx/room/processor/TableEntityProcessor.kt
+++ b/room/room-compiler/src/main/kotlin/androidx/room/processor/TableEntityProcessor.kt
@@ -123,7 +123,7 @@
                     )
                 }
             }
-        val superIndices = loadSuperIndices(element.superType, tableName, inheritSuperIndices)
+        val superIndices = loadSuperIndices(element.superClass, tableName, inheritSuperIndices)
         val indexInputs = entityIndices + fieldIndices + superIndices
         val indices = validateAndCreateIndices(indexInputs, pojo)
 
@@ -387,7 +387,7 @@
             }
         } ?: emptyList()
         // checks supers.
-        val mySuper = typeElement.superType
+        val mySuper = typeElement.superClass
         val superPKeys = if (mySuper != null && mySuper.isNotNone()) {
             // my super cannot see my fields so remove them.
             val remainingFields = availableFields.filterNot {
@@ -444,7 +444,7 @@
             myPKeys.first()
         } else if (myPKeys.isEmpty()) {
             // i have not declared anything, delegate to super
-            val mySuper = typeElement.superType
+            val mySuper = typeElement.superClass
             if (mySuper != null && mySuper.isNotNone()) {
                 return choosePrimaryKey(candidates, mySuper.typeElement!!)
             }
@@ -567,6 +567,6 @@
                     emptyList()
                 }
             } ?: emptyList()
-        return myIndices + loadSuperIndices(parentTypeElement.superType, tableName, inherit)
+        return myIndices + loadSuperIndices(parentTypeElement.superClass, tableName, inherit)
     }
 }