Merge "Reduce XElement API surface" into androidx-master-dev
diff --git a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/XElement.kt b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/XElement.kt
index 4d177d9..3fafecb 100644
--- a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/XElement.kt
+++ b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/XElement.kt
@@ -29,64 +29,6 @@
  */
 interface XElement {
     /**
-     * SimpleName of the element converted to a String.
-     *
-     * @see [javax.lang.model.element.Element.getSimpleName]
-     */
-    val name: String
-
-    /**
-     * The qualified name of the package that contains this element.
-     */
-    val packageName: String
-
-    /**
-     * The [XElement] that contains this element.
-     *
-     * For inner classes, this will be another [XTypeElement].
-     * For top level classes, it will be null as x-processing does not model packages or modules.
-     *
-     * For [XExecutableElement], it will be the [XTypeElement] where the method is declared.
-     */
-    val enclosingElement: XElement?
-
-    /**
-     * Returns `true` if this element is public (has public modifier in Java or not marked as
-     * private / internal in Kotlin).
-     */
-    fun isPublic(): Boolean
-
-    /**
-     * Returns `true` if this element has protected modifier.
-     */
-    fun isProtected(): Boolean
-
-    /**
-     * Returns `true` if this element is declared as abstract.
-     */
-    fun isAbstract(): Boolean
-
-    /**
-     * Returns `true` if this element has private modifier.
-     */
-    fun isPrivate(): Boolean
-
-    /**
-     * Returns `true` if this element has static modifier.
-     */
-    fun isStatic(): Boolean
-
-    /**
-     * Returns `true` if this element has transient modifier.
-     */
-    fun isTransient(): Boolean
-
-    /**
-     * Returns `true` if this element is final and cannot be overridden.
-     */
-    fun isFinal(): Boolean
-
-    /**
      * Returns the string representation of the Element's kind.
      */
     fun kindName(): String
diff --git a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/XExecutableElement.kt b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/XExecutableElement.kt
index 4187d44f..e378882 100644
--- a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/XExecutableElement.kt
+++ b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/XExecutableElement.kt
@@ -21,18 +21,17 @@
  *
  * @see [javax.lang.model.element.ExecutableElement]
  */
-interface XExecutableElement : XElement {
+interface XExecutableElement : XHasModifiers, XElement {
     /**
-     * The [XTypeElement] that contains this method.
+     * The [XTypeElement] that declared this executable.
      */
-    override val enclosingElement: XTypeElement
-
+    val enclosingTypeElement: XTypeElement
     /**
      * The list of parameters that should be passed into this method.
      *
      * @see [isVarArgs]
      */
-    val parameters: List<XVariableElement>
+    val parameters: List<XExecutableParameterElement>
     /**
      * Returns true if this method receives a vararg parameter.
      */
diff --git a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/XExecutableParameterElement.kt b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/XExecutableParameterElement.kt
new file mode 100644
index 0000000..8e7ed20
--- /dev/null
+++ b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/XExecutableParameterElement.kt
@@ -0,0 +1,22 @@
+/*
+ * 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
+
+/**
+ * Parameter of a method.
+ */
+interface XExecutableParameterElement : XVariableElement
diff --git a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/XFieldElement.kt b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/XFieldElement.kt
new file mode 100644
index 0000000..fe68eee
--- /dev/null
+++ b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/XFieldElement.kt
@@ -0,0 +1,27 @@
+/*
+ * 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
+
+/**
+ * Field in an [XTypeElement].
+ */
+interface XFieldElement : XVariableElement, XHasModifiers {
+    /**
+     * The [XTypeElement] that declared this executable.
+     */
+    val enclosingTypeElement: XTypeElement
+}
\ No newline at end of file
diff --git a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/XHasModifiers.kt b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/XHasModifiers.kt
new file mode 100644
index 0000000..83a5786
--- /dev/null
+++ b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/XHasModifiers.kt
@@ -0,0 +1,58 @@
+/*
+ * 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
+
+/**
+ * Common interface for elements which might have modifiers (e.g. field, method, class)
+ */
+interface XHasModifiers {
+    /**
+     * Returns `true` if this element is public (has public modifier in Java or not marked as
+     * private / internal in Kotlin).
+     */
+    fun isPublic(): Boolean
+
+    /**
+     * Returns `true` if this element has protected modifier.
+     */
+    fun isProtected(): Boolean
+
+    /**
+     * Returns `true` if this element is declared as abstract.
+     */
+    fun isAbstract(): Boolean
+
+    /**
+     * Returns `true` if this element has private modifier.
+     */
+    fun isPrivate(): Boolean
+
+    /**
+     * Returns `true` if this element has static modifier.
+     */
+    fun isStatic(): Boolean
+
+    /**
+     * Returns `true` if this element has transient modifier.
+     */
+    fun isTransient(): Boolean
+
+    /**
+     * Returns `true` if this element is final and cannot be overridden.
+     */
+    fun isFinal(): Boolean
+}
diff --git a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/XMethodElement.kt b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/XMethodElement.kt
index 02384a9..0d6b1ac 100644
--- a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/XMethodElement.kt
+++ b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/XMethodElement.kt
@@ -24,6 +24,11 @@
  */
 interface XMethodElement : XExecutableElement {
     /**
+     * The name of the method.
+     */
+    val name: String
+
+    /**
      * The return type for the method. Note that it might be [XType.isNone] if it does not return or
      * [XType.isError] if the return type cannot be resolved.
      */
diff --git a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/XTypeElement.kt b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/XTypeElement.kt
index 7c7cb1b..614f1a3 100644
--- a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/XTypeElement.kt
+++ b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/XTypeElement.kt
@@ -18,13 +18,25 @@
 
 import com.squareup.javapoet.ClassName
 
-interface XTypeElement : XElement {
+interface XTypeElement : XHasModifiers, XElement {
     /**
      * The qualified name of the Class/Interface.
      */
     val qualifiedName: String
 
     /**
+     * The qualified name of the package that contains this element.
+     */
+    val packageName: String
+
+    /**
+     * SimpleName of the type converted to String.
+     *
+     * @see [javax.lang.model.element.Element.getSimpleName]
+     */
+    val name: String
+
+    /**
      * The type represented by this [XTypeElement].
      */
     val type: XDeclaredType
@@ -40,6 +52,11 @@
     val className: ClassName
 
     /**
+     * The [XTypeElement] that contains this [XTypeElement] if it is an inner class/interface.
+     */
+    val enclosingTypeElement: XTypeElement?
+
+    /**
      * Returns `true` if this [XTypeElement] represents an interface
      */
     fun isInterface(): Boolean
@@ -53,7 +70,7 @@
      * All fields, including private supers.
      * Room only ever reads fields this way.
      */
-    fun getAllFieldsIncludingPrivateSupers(): List<XVariableElement>
+    fun getAllFieldsIncludingPrivateSupers(): List<XFieldElement>
 
     /**
      * Returns the primary constructor for the type, if it exists.
diff --git a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/XVariableElement.kt b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/XVariableElement.kt
index 572dcf6..892458a 100644
--- a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/XVariableElement.kt
+++ b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/XVariableElement.kt
@@ -21,6 +21,11 @@
  */
 interface XVariableElement : XElement {
     /**
+     * The name of the variable element.
+     */
+    val name: String
+
+    /**
      * Returns the type of this field or parameter
      */
     val type: XType
diff --git a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/javac/ElementExt.kt b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/javac/ElementExt.kt
index c91f4e9..372496c 100644
--- a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/javac/ElementExt.kt
+++ b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/javac/ElementExt.kt
@@ -35,6 +35,7 @@
     androidx.annotation.Nullable::class.java,
     org.jetbrains.annotations.Nullable::class.java
 )
+
 /**
  * gets all members including super privates. does not handle duplicate field names!!!
  */
@@ -66,3 +67,18 @@
     } else {
         XNullability.UNKNOWN
     }
+
+internal fun Element.requireEnclosingType(env: JavacProcessingEnv): JavacTypeElement {
+    return checkNotNull(enclosingType(env)) {
+        "Cannot find required enclosing type for $this"
+    }
+}
+
+@Suppress("UnstableApiUsage")
+internal fun Element.enclosingType(env: JavacProcessingEnv): JavacTypeElement? {
+    return if (MoreElements.isType(enclosingElement)) {
+        env.wrapTypeElement(MoreElements.asType(enclosingElement))
+    } else {
+        null
+    }
+}
\ No newline at end of file
diff --git a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacConstructorElement.kt b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacConstructorElement.kt
index 940234d..2144339 100644
--- a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacConstructorElement.kt
+++ b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacConstructorElement.kt
@@ -17,6 +17,7 @@
 package androidx.room.compiler.processing.javac
 
 import androidx.room.compiler.processing.XConstructorElement
+import androidx.room.compiler.processing.XTypeElement
 import androidx.room.compiler.processing.javac.kotlin.KmConstructor
 import javax.lang.model.element.ElementKind
 import javax.lang.model.element.ExecutableElement
@@ -36,7 +37,11 @@
         }
     }
 
+    override val enclosingTypeElement: XTypeElement by lazy {
+        element.requireEnclosingType(env)
+    }
+
     override val kotlinMetadata: KmConstructor? by lazy {
-        (enclosingElement as? JavacTypeElement)?.kotlinMetadata?.getConstructorMetadata(element)
+        (enclosingTypeElement as? JavacTypeElement)?.kotlinMetadata?.getConstructorMetadata(element)
     }
 }
diff --git a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacElement.kt b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacElement.kt
index 24ec6a6..d12eb4d 100644
--- a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacElement.kt
+++ b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacElement.kt
@@ -22,7 +22,6 @@
 import com.google.auto.common.MoreElements
 import java.util.Locale
 import javax.lang.model.element.Element
-import javax.lang.model.element.Modifier
 import kotlin.reflect.KClass
 
 @Suppress("UnstableApiUsage")
@@ -30,52 +29,6 @@
     protected val env: JavacProcessingEnv,
     open val element: Element
 ) : XElement, XEquality {
-
-    override val name: String
-        get() = element.simpleName.toString()
-
-    override val packageName: String
-        get() = MoreElements.getPackage(element).qualifiedName.toString()
-
-    override val enclosingElement: XElement? by lazy {
-        val enclosing = element.enclosingElement
-        if (MoreElements.isType(enclosing)) {
-            env.wrapTypeElement(MoreElements.asType(enclosing))
-        } else {
-            // room only cares if it is another type as we do not model packages
-            // or modules.
-            null
-        }
-    }
-
-    override fun isPublic(): Boolean {
-        return element.modifiers.contains(Modifier.PUBLIC)
-    }
-
-    override fun isProtected(): Boolean {
-        return element.modifiers.contains(Modifier.PROTECTED)
-    }
-
-    override fun isAbstract(): Boolean {
-        return element.modifiers.contains(Modifier.ABSTRACT)
-    }
-
-    override fun isPrivate(): Boolean {
-        return element.modifiers.contains(Modifier.PRIVATE)
-    }
-
-    override fun isStatic(): Boolean {
-        return element.modifiers.contains(Modifier.STATIC)
-    }
-
-    override fun isTransient(): Boolean {
-        return element.modifiers.contains(Modifier.TRANSIENT)
-    }
-
-    override fun isFinal(): Boolean {
-        return element.modifiers.contains(Modifier.FINAL)
-    }
-
     override fun <T : Annotation> toAnnotationBox(annotation: KClass<T>): XAnnotationBox<T>? {
         return MoreElements
             .getAnnotationMirror(element, annotation.java)
diff --git a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacExecutableElement.kt b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacExecutableElement.kt
index 79c7b6e..c1a0648 100644
--- a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacExecutableElement.kt
+++ b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacExecutableElement.kt
@@ -17,7 +17,7 @@
 package androidx.room.compiler.processing.javac
 
 import androidx.room.compiler.processing.XExecutableElement
-import androidx.room.compiler.processing.XTypeElement
+import androidx.room.compiler.processing.XHasModifiers
 import androidx.room.compiler.processing.javac.kotlin.KmExecutable
 import androidx.room.compiler.processing.javac.kotlin.descriptor
 import javax.lang.model.element.ExecutableElement
@@ -29,16 +29,13 @@
 ) : JavacElement(
     env,
     element
-), XExecutableElement {
+), XExecutableElement, XHasModifiers by JavacHasModifiers(element) {
     abstract val kotlinMetadata: KmExecutable?
 
     val descriptor by lazy {
         element.descriptor()
     }
 
-    override val enclosingElement: XTypeElement
-        get() = super.enclosingElement as XTypeElement
-
     override val parameters: List<JavacVariableElement> by lazy {
         element.parameters.mapIndexed { index, variable ->
             JavacMethodParameter(
diff --git a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacFieldElement.kt b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacFieldElement.kt
index 1e7cd4c..2ae7beb 100644
--- a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacFieldElement.kt
+++ b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacFieldElement.kt
@@ -16,6 +16,9 @@
 
 package androidx.room.compiler.processing.javac
 
+import androidx.room.compiler.processing.XFieldElement
+import androidx.room.compiler.processing.XHasModifiers
+import androidx.room.compiler.processing.XTypeElement
 import androidx.room.compiler.processing.javac.kotlin.KmProperty
 import androidx.room.compiler.processing.javac.kotlin.KmType
 import javax.lang.model.element.VariableElement
@@ -24,10 +27,18 @@
     env: JavacProcessingEnv,
     containing: JavacTypeElement,
     element: VariableElement
-) : JavacVariableElement(env, containing, element) {
+) : JavacVariableElement(env, containing, element),
+    XFieldElement,
+    XHasModifiers by JavacHasModifiers(element) {
+
     private val kotlinMetadata: KmProperty? by lazy {
-        (enclosingElement as? JavacTypeElement)?.kotlinMetadata?.getPropertyMetadata(name)
+        (enclosingTypeElement as? JavacTypeElement)?.kotlinMetadata?.getPropertyMetadata(name)
     }
+
     override val kotlinType: KmType?
         get() = kotlinMetadata?.type
+
+    override val enclosingTypeElement: XTypeElement by lazy {
+        element.requireEnclosingType(env)
+    }
 }
diff --git a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacHasModifiers.kt b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacHasModifiers.kt
new file mode 100644
index 0000000..7b841f1
--- /dev/null
+++ b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacHasModifiers.kt
@@ -0,0 +1,55 @@
+/*
+ * 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.javac
+
+import androidx.room.compiler.processing.XHasModifiers
+import javax.lang.model.element.Element
+import javax.lang.model.element.Modifier
+
+/**
+ * Implementation of [XHasModifiers] for java elements
+ */
+internal class JavacHasModifiers(private val element: Element) : XHasModifiers {
+
+    override fun isPublic(): Boolean {
+        return element.modifiers.contains(Modifier.PUBLIC)
+    }
+
+    override fun isProtected(): Boolean {
+        return element.modifiers.contains(Modifier.PROTECTED)
+    }
+
+    override fun isAbstract(): Boolean {
+        return element.modifiers.contains(Modifier.ABSTRACT)
+    }
+
+    override fun isPrivate(): Boolean {
+        return element.modifiers.contains(Modifier.PRIVATE)
+    }
+
+    override fun isStatic(): Boolean {
+        return element.modifiers.contains(Modifier.STATIC)
+    }
+
+    override fun isTransient(): Boolean {
+        return element.modifiers.contains(Modifier.TRANSIENT)
+    }
+
+    override fun isFinal(): Boolean {
+        return element.modifiers.contains(Modifier.FINAL)
+    }
+}
\ No newline at end of file
diff --git a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacMethodElement.kt b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacMethodElement.kt
index f49c32a3..cfa6577 100644
--- a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacMethodElement.kt
+++ b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacMethodElement.kt
@@ -19,6 +19,7 @@
 import androidx.room.compiler.processing.XDeclaredType
 import androidx.room.compiler.processing.XMethodElement
 import androidx.room.compiler.processing.XMethodType
+import androidx.room.compiler.processing.XTypeElement
 import androidx.room.compiler.processing.XVariableElement
 import androidx.room.compiler.processing.javac.kotlin.KmFunction
 import com.google.auto.common.MoreElements
@@ -42,8 +43,16 @@
             "Method element is constructed with invalid type: $element"
         }
     }
+
+    override val name: String
+        get() = element.simpleName.toString()
+
+    override val enclosingTypeElement: XTypeElement by lazy {
+        element.requireEnclosingType(env)
+    }
+
     override val kotlinMetadata: KmFunction? by lazy {
-        (enclosingElement as? JavacTypeElement)?.kotlinMetadata?.getFunctionMetadata(element)
+        (enclosingTypeElement as? JavacTypeElement)?.kotlinMetadata?.getFunctionMetadata(element)
     }
 
     override val executableType: JavacMethodType by lazy {
diff --git a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacTypeElement.kt b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacTypeElement.kt
index 836fc5b..91fb81e 100644
--- a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacTypeElement.kt
+++ b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacTypeElement.kt
@@ -16,8 +16,9 @@
 
 package androidx.room.compiler.processing.javac
 
+import androidx.room.compiler.processing.XFieldElement
+import androidx.room.compiler.processing.XHasModifiers
 import androidx.room.compiler.processing.XTypeElement
-import androidx.room.compiler.processing.XVariableElement
 import androidx.room.compiler.processing.javac.kotlin.KotlinMetadataElement
 import com.google.auto.common.MoreElements
 import com.squareup.javapoet.ClassName
@@ -29,7 +30,14 @@
 internal class JavacTypeElement(
     env: JavacProcessingEnv,
     override val element: TypeElement
-) : JavacElement(env, element), XTypeElement {
+) : JavacElement(env, element), XTypeElement, XHasModifiers by JavacHasModifiers(element) {
+
+    override val name: String
+        get() = element.simpleName.toString()
+
+    @Suppress("UnstableApiUsage")
+    override val packageName: String
+        get() = MoreElements.getPackage(element).qualifiedName.toString()
 
     val kotlinMetadata by lazy {
         KotlinMetadataElement.createFor(element)
@@ -42,6 +50,9 @@
     override val className: ClassName by lazy {
         ClassName.get(element)
     }
+    override val enclosingTypeElement: XTypeElement? by lazy {
+        element.enclosingType(env)
+    }
 
     override fun isInterface() = element.kind == ElementKind.INTERFACE
 
@@ -57,7 +68,7 @@
         }
     }
 
-    override fun getAllFieldsIncludingPrivateSupers(): List<XVariableElement> {
+    override fun getAllFieldsIncludingPrivateSupers(): List<XFieldElement> {
         return _allFieldsIncludingPrivateSupers
     }
 
diff --git a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacVariableElement.kt b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacVariableElement.kt
index 643db6b..4e4abba8 100644
--- a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacVariableElement.kt
+++ b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/javac/JavacVariableElement.kt
@@ -17,8 +17,8 @@
 package androidx.room.compiler.processing.javac
 
 import androidx.room.compiler.processing.XDeclaredType
+import androidx.room.compiler.processing.XExecutableParameterElement
 import androidx.room.compiler.processing.XType
-import androidx.room.compiler.processing.XVariableElement
 import androidx.room.compiler.processing.javac.kotlin.KmType
 import com.google.auto.common.MoreTypes
 import javax.lang.model.element.VariableElement
@@ -27,8 +27,13 @@
     env: JavacProcessingEnv,
     val containing: JavacTypeElement,
     override val element: VariableElement
-) : JavacElement(env, element), XVariableElement {
+) : JavacElement(env, element), XExecutableParameterElement {
+
     abstract val kotlinType: KmType?
+
+    override val name: String
+        get() = element.simpleName.toString()
+
     override val type: JavacType by lazy {
         MoreTypes.asMemberOf(env.typeUtils, containing.type.typeMirror, element).let {
             env.wrap<JavacType>(
diff --git a/room/compiler-processing/src/test/java/androidx/room/compiler/processing/XElementTest.kt b/room/compiler-processing/src/test/java/androidx/room/compiler/processing/XElementTest.kt
index fa40df03..813e531 100644
--- a/room/compiler-processing/src/test/java/androidx/room/compiler/processing/XElementTest.kt
+++ b/room/compiler-processing/src/test/java/androidx/room/compiler/processing/XElementTest.kt
@@ -60,7 +60,7 @@
             )
         ) {
             val element = it.processingEnv.requireTypeElement("foo.bar.Baz")
-            fun XElement.readModifiers(): Set<String> {
+            fun XHasModifiers.readModifiers(): Set<String> {
                 val result = mutableSetOf<String>()
                 if (isPrivate()) result.add("private")
                 if (isPublic()) result.add("public")
@@ -72,7 +72,7 @@
                 return result
             }
 
-            fun XElement.assertModifiers(vararg expected: String) {
+            fun XHasModifiers.assertModifiers(vararg expected: String) {
                 assertThat(readModifiers()).containsExactlyElementsIn(expected)
             }
             element.assertModifiers("abstract", "public")
diff --git a/room/compiler/src/main/kotlin/androidx/room/processor/DatabaseProcessor.kt b/room/compiler/src/main/kotlin/androidx/room/processor/DatabaseProcessor.kt
index 75c6368..5c42523 100644
--- a/room/compiler/src/main/kotlin/androidx/room/processor/DatabaseProcessor.kt
+++ b/room/compiler/src/main/kotlin/androidx/room/processor/DatabaseProcessor.kt
@@ -81,7 +81,7 @@
             it.isAbstract()
         }.filterNot {
             // remove methods that belong to room
-            val containing = it.enclosingElement
+            val containing = it.enclosingTypeElement
             containing.isType() &&
                     containing.asDeclaredType().typeName == RoomTypeNames.ROOM_DB
         }.map {
diff --git a/room/compiler/src/main/kotlin/androidx/room/processor/FieldProcessor.kt b/room/compiler/src/main/kotlin/androidx/room/processor/FieldProcessor.kt
index 9f5bd98..96ea9db 100644
--- a/room/compiler/src/main/kotlin/androidx/room/processor/FieldProcessor.kt
+++ b/room/compiler/src/main/kotlin/androidx/room/processor/FieldProcessor.kt
@@ -17,10 +17,10 @@
 package androidx.room.processor
 
 import androidx.room.ColumnInfo
+import androidx.room.compiler.processing.XDeclaredType
+import androidx.room.compiler.processing.XFieldElement
 import androidx.room.parser.Collate
 import androidx.room.parser.SQLTypeAffinity
-import androidx.room.compiler.processing.XDeclaredType
-import androidx.room.compiler.processing.XVariableElement
 import androidx.room.vo.EmbeddedField
 import androidx.room.vo.Field
 import java.util.Locale
@@ -28,7 +28,7 @@
 class FieldProcessor(
     baseContext: Context,
     val containing: XDeclaredType,
-    val element: XVariableElement,
+    val element: XFieldElement,
     val bindingScope: BindingScope,
     val fieldParent: EmbeddedField?, // pass only if this is processed as a child of Embedded field
     val onBindingError: (field: Field, errorMsg: String) -> Unit
diff --git a/room/compiler/src/main/kotlin/androidx/room/processor/FtsTableEntityProcessor.kt b/room/compiler/src/main/kotlin/androidx/room/processor/FtsTableEntityProcessor.kt
index 796e832..c522647 100644
--- a/room/compiler/src/main/kotlin/androidx/room/processor/FtsTableEntityProcessor.kt
+++ b/room/compiler/src/main/kotlin/androidx/room/processor/FtsTableEntityProcessor.kt
@@ -178,7 +178,7 @@
                                         fields.map { it.columnName }))
                         field?.let { pkField ->
                             PrimaryKey(
-                                    declaredIn = pkField.element.enclosingElement,
+                                    declaredIn = pkField.element.enclosingTypeElement,
                                     fields = Fields(pkField),
                                     autoGenerateId = true)
                         }
@@ -187,7 +187,7 @@
         val keysFromPrimaryKeyAnnotations = fields.mapNotNull { field ->
             if (field.element.hasAnnotation(androidx.room.PrimaryKey::class)) {
                 PrimaryKey(
-                        declaredIn = field.element.enclosingElement,
+                        declaredIn = field.element.enclosingTypeElement,
                         fields = Fields(field),
                         autoGenerateId = true)
             } else {
diff --git a/room/compiler/src/main/kotlin/androidx/room/processor/PojoProcessor.kt b/room/compiler/src/main/kotlin/androidx/room/processor/PojoProcessor.kt
index d42478e..31b9f4b 100644
--- a/room/compiler/src/main/kotlin/androidx/room/processor/PojoProcessor.kt
+++ b/room/compiler/src/main/kotlin/androidx/room/processor/PojoProcessor.kt
@@ -24,6 +24,7 @@
 import androidx.room.Relation
 import androidx.room.compiler.processing.XDeclaredType
 import androidx.room.compiler.processing.XExecutableElement
+import androidx.room.compiler.processing.XFieldElement
 import androidx.room.compiler.processing.XType
 import androidx.room.compiler.processing.XTypeElement
 import androidx.room.compiler.processing.XVariableElement
@@ -370,7 +371,7 @@
 
     private fun processEmbeddedField(
         declaredType: XDeclaredType,
-        variableElement: XVariableElement
+        variableElement: XFieldElement
     ): EmbeddedField? {
         val asMemberType = variableElement.asMemberOf(declaredType)
         val asTypeElement = asMemberType.asTypeElement()
@@ -403,7 +404,7 @@
     private fun processRelationField(
         myFields: List<Field>,
         container: XDeclaredType?,
-        relationElement: XVariableElement
+        relationElement: XFieldElement
     ): androidx.room.vo.Relation? {
         val annotation = relationElement.toAnnotationBox(Relation::class)!!
 
diff --git a/room/compiler/src/main/kotlin/androidx/room/processor/TableEntityProcessor.kt b/room/compiler/src/main/kotlin/androidx/room/processor/TableEntityProcessor.kt
index feedb3a..eb2597f 100644
--- a/room/compiler/src/main/kotlin/androidx/room/processor/TableEntityProcessor.kt
+++ b/room/compiler/src/main/kotlin/androidx/room/processor/TableEntityProcessor.kt
@@ -95,12 +95,12 @@
                                         it.getPath(), element.qualifiedName
                                 ))
                         null
-                    } else if (it.element.enclosingElement != element && !inheritSuperIndices) {
+                    } else if (it.element.enclosingTypeElement != element && !inheritSuperIndices) {
                         it.indexed = false
                         context.logger.w(Warning.INDEX_FROM_PARENT_FIELD_IS_DROPPED,
                                 ProcessorErrors.droppedSuperClassFieldIndex(
                                         it.columnName, element.toString(),
-                                        it.element.enclosingElement.toString()
+                                        it.element.enclosingTypeElement.toString()
                                 ))
                         null
                     } else {
@@ -311,7 +311,7 @@
                                 element.qualifiedName, field.name))
                     null
                 } else {
-                    PrimaryKey(declaredIn = field.element.enclosingElement,
+                    PrimaryKey(declaredIn = field.element.enclosingTypeElement,
                             fields = Fields(field),
                             autoGenerateId = it.value.autoGenerate)
                 }
@@ -348,7 +348,7 @@
         val superPKeys = if (mySuper != null && mySuper.isNotNone()) {
             // my super cannot see my fields so remove them.
             val remainingFields = availableFields.filterNot {
-                it.element.enclosingElement == typeElement
+                it.element.enclosingTypeElement == typeElement
             }
             collectPrimaryKeysFromEntityAnnotations(mySuper.asTypeElement(), remainingFields)
         } else {
@@ -365,7 +365,7 @@
                 context.checker.check(!it.value.autoGenerate || embeddedField.pojo.fields.size == 1,
                         embeddedField.field.element,
                         ProcessorErrors.AUTO_INCREMENT_EMBEDDED_HAS_MULTIPLE_FIELDS)
-                PrimaryKey(declaredIn = embeddedField.field.element.enclosingElement,
+                PrimaryKey(declaredIn = embeddedField.field.element.enclosingTypeElement,
                         fields = embeddedField.pojo.fields,
                         autoGenerateId = it.value.autoGenerate)
             }
diff --git a/room/compiler/src/main/kotlin/androidx/room/processor/autovalue/AutoValuePojoProcessorDelegate.kt b/room/compiler/src/main/kotlin/androidx/room/processor/autovalue/AutoValuePojoProcessorDelegate.kt
index 16c9c05..42aac34f 100644
--- a/room/compiler/src/main/kotlin/androidx/room/processor/autovalue/AutoValuePojoProcessorDelegate.kt
+++ b/room/compiler/src/main/kotlin/androidx/room/processor/autovalue/AutoValuePojoProcessorDelegate.kt
@@ -104,8 +104,8 @@
         fun getGeneratedClassName(element: XTypeElement): String {
             var type = element
             var name = type.name
-            while (type.enclosingElement?.isType() == true) {
-                type = type.enclosingElement!!.asTypeElement()
+            while (type.enclosingTypeElement?.isType() == true) {
+                type = type.enclosingTypeElement!!.asTypeElement()
                 name = "${type.name}_$name"
             }
             val pkg = type.packageName
diff --git a/room/compiler/src/main/kotlin/androidx/room/vo/Constructor.kt b/room/compiler/src/main/kotlin/androidx/room/vo/Constructor.kt
index a8082ea..ba15d80 100644
--- a/room/compiler/src/main/kotlin/androidx/room/vo/Constructor.kt
+++ b/room/compiler/src/main/kotlin/androidx/room/vo/Constructor.kt
@@ -44,11 +44,11 @@
         when {
             element.isConstructor() -> {
                 builder.addStatement("$L = new $T($L)", outVar,
-                        element.enclosingElement.asDeclaredType().typeName, args)
+                        element.enclosingTypeElement.asDeclaredType().typeName, args)
             }
             element.isMethod() -> {
                 builder.addStatement("$L = $T.$L($L)", outVar,
-                        element.enclosingElement.asDeclaredType().typeName,
+                        element.enclosingTypeElement.asDeclaredType().typeName,
                         element.name, args)
             }
             else -> throw IllegalStateException("Invalid constructor kind ${element.kindName()}")
diff --git a/room/compiler/src/main/kotlin/androidx/room/vo/Dao.kt b/room/compiler/src/main/kotlin/androidx/room/vo/Dao.kt
index 790b3af..02c1852 100644
--- a/room/compiler/src/main/kotlin/androidx/room/vo/Dao.kt
+++ b/room/compiler/src/main/kotlin/androidx/room/vo/Dao.kt
@@ -55,10 +55,10 @@
             suffix = ""
         }
         val path = arrayListOf<String>()
-        var enclosing = element.enclosingElement
+        var enclosing = element.enclosingTypeElement
         while (enclosing?.isType() == true) {
             path.add(enclosing!!.name)
-            enclosing = enclosing!!.enclosingElement
+            enclosing = enclosing!!.enclosingTypeElement
         }
         path.reversed().joinToString("_") + "${typeName.simpleName()}${suffix}_Impl"
     }
diff --git a/room/compiler/src/main/kotlin/androidx/room/vo/Field.kt b/room/compiler/src/main/kotlin/androidx/room/vo/Field.kt
index 529bebd..a687db7 100644
--- a/room/compiler/src/main/kotlin/androidx/room/vo/Field.kt
+++ b/room/compiler/src/main/kotlin/androidx/room/vo/Field.kt
@@ -16,12 +16,12 @@
 
 package androidx.room.vo
 
+import androidx.room.compiler.processing.XFieldElement
+import androidx.room.compiler.processing.XNullability
+import androidx.room.compiler.processing.XType
 import androidx.room.migration.bundle.FieldBundle
 import androidx.room.parser.Collate
 import androidx.room.parser.SQLTypeAffinity
-import androidx.room.compiler.processing.XNullability
-import androidx.room.compiler.processing.XType
-import androidx.room.compiler.processing.XVariableElement
 import androidx.room.solver.types.CursorValueReader
 import androidx.room.solver.types.StatementValueBinder
 import capitalize
@@ -31,7 +31,7 @@
 
 // used in cache matching, must stay as a data class or implement equals
 data class Field(
-    val element: XVariableElement,
+    val element: XFieldElement,
     val name: String,
     val type: XType,
     var affinity: SQLTypeAffinity?,
diff --git a/room/compiler/src/test/kotlin/androidx/room/ext/ElementExtTest.kt b/room/compiler/src/test/kotlin/androidx/room/ext/ElementExtTest.kt
index 8c28942..e9d0617 100644
--- a/room/compiler/src/test/kotlin/androidx/room/ext/ElementExtTest.kt
+++ b/room/compiler/src/test/kotlin/androidx/room/ext/ElementExtTest.kt
@@ -16,7 +16,7 @@
 
 package androidx.room.ext
 
-import androidx.room.compiler.processing.XExecutableElement
+import androidx.room.compiler.processing.XMethodElement
 import com.google.common.truth.Truth.assertThat
 import com.google.testing.compile.JavaFileObjects
 import com.squareup.javapoet.ClassName
@@ -102,8 +102,8 @@
                             ) + "overridden" // add 1 overridden back
                 )
 
-            assertThat(child.getConstructors()).containsExactly("<init>")
-            assertThat(parent.getConstructors()).containsExactly("<init>")
+            assertThat(child.getConstructors()).hasSize(1)
+            assertThat(parent.getConstructors()).hasSize(1)
         }.compilesWithoutError()
     }
 
@@ -229,7 +229,7 @@
         }.compilesWithoutError()
     }
 
-    private fun assertThat(executables: Iterable<XExecutableElement>) = assertThat(
+    private fun assertThat(executables: Iterable<XMethodElement>) = assertThat(
         executables.map { it.name }
     )
 }
\ No newline at end of file
diff --git a/room/compiler/src/test/kotlin/androidx/room/processor/FieldProcessorTest.kt b/room/compiler/src/test/kotlin/androidx/room/processor/FieldProcessorTest.kt
index 4c5939c..5def604 100644
--- a/room/compiler/src/test/kotlin/androidx/room/processor/FieldProcessorTest.kt
+++ b/room/compiler/src/test/kotlin/androidx/room/processor/FieldProcessorTest.kt
@@ -17,9 +17,9 @@
 package androidx.room.processor
 
 import androidx.room.Entity
+import androidx.room.compiler.processing.XFieldElement
 import androidx.room.parser.Collate
 import androidx.room.parser.SQLTypeAffinity
-import androidx.room.compiler.processing.XVariableElement
 import androidx.room.solver.types.ColumnTypeAdapter
 import androidx.room.testing.TestInvocation
 import androidx.room.testing.TestProcessor
@@ -242,12 +242,12 @@
     @Test
     fun nameVariations() {
         simpleRun {
-            val variableElement = mock(XVariableElement::class.java)
-            assertThat(Field(variableElement, "x", TypeName.INT.typeMirror(it),
+            val fieldElement = mock(XFieldElement::class.java)
+            assertThat(Field(fieldElement, "x", TypeName.INT.typeMirror(it),
                     SQLTypeAffinity.INTEGER).nameWithVariations, `is`(arrayListOf("x")))
-            assertThat(Field(variableElement, "x", TypeName.BOOLEAN.typeMirror(it),
+            assertThat(Field(fieldElement, "x", TypeName.BOOLEAN.typeMirror(it),
                     SQLTypeAffinity.INTEGER).nameWithVariations, `is`(arrayListOf("x")))
-            assertThat(Field(variableElement, "xAll",
+            assertThat(Field(fieldElement, "xAll",
                 TypeName.BOOLEAN.typeMirror(it), SQLTypeAffinity.INTEGER)
                     .nameWithVariations, `is`(arrayListOf("xAll")))
         }
@@ -255,7 +255,7 @@
 
     @Test
     fun nameVariations_is() {
-        val elm = mock(XVariableElement::class.java)
+        val elm = mock(XFieldElement::class.java)
         simpleRun {
             assertThat(Field(elm, "isX", TypeName.BOOLEAN.typeMirror(it),
                     SQLTypeAffinity.INTEGER).nameWithVariations, `is`(arrayListOf("isX", "x")))
@@ -271,7 +271,7 @@
 
     @Test
     fun nameVariations_has() {
-        val elm = mock(XVariableElement::class.java)
+        val elm = mock(XFieldElement::class.java)
         simpleRun {
             assertThat(Field(elm, "hasX", TypeName.BOOLEAN.typeMirror(it),
                     SQLTypeAffinity.INTEGER).nameWithVariations, `is`(arrayListOf("hasX", "x")))
@@ -287,7 +287,7 @@
 
     @Test
     fun nameVariations_m() {
-        val elm = mock(XVariableElement::class.java)
+        val elm = mock(XFieldElement::class.java)
         simpleRun {
             assertThat(Field(elm, "mall", TypeName.BOOLEAN.typeMirror(it),
                     SQLTypeAffinity.INTEGER).nameWithVariations, `is`(arrayListOf("mall")))
@@ -308,7 +308,7 @@
 
     @Test
     fun nameVariations_underscore() {
-        val elm = mock(XVariableElement::class.java)
+        val elm = mock(XFieldElement::class.java)
         simpleRun {
             assertThat(Field(elm, "_all", TypeName.BOOLEAN.typeMirror(it),
                     SQLTypeAffinity.INTEGER).nameWithVariations, `is`(arrayListOf("_all", "all")))
@@ -436,7 +436,7 @@
                             val parser = FieldProcessor(
                                     baseContext = entityContext,
                                     containing = owner.asDeclaredType(),
-                                    element = fieldElement!!.asVariableElement(),
+                                    element = fieldElement!!,
                                     bindingScope = FieldProcessor.BindingScope.TWO_WAY,
                                     fieldParent = null,
                                     onBindingError = { field, errorMsg ->
diff --git a/room/compiler/src/test/kotlin/androidx/room/processor/PojoProcessorTest.kt b/room/compiler/src/test/kotlin/androidx/room/processor/PojoProcessorTest.kt
index 2adafd4..245bdee 100644
--- a/room/compiler/src/test/kotlin/androidx/room/processor/PojoProcessorTest.kt
+++ b/room/compiler/src/test/kotlin/androidx/room/processor/PojoProcessorTest.kt
@@ -18,8 +18,8 @@
 
 import COMMON
 import androidx.room.Embedded
+import androidx.room.compiler.processing.XFieldElement
 import androidx.room.parser.SQLTypeAffinity
-import androidx.room.compiler.processing.XVariableElement
 import androidx.room.processor.ProcessorErrors.CANNOT_FIND_GETTER_FOR_FIELD
 import androidx.room.processor.ProcessorErrors.CANNOT_FIND_TYPE
 import androidx.room.processor.ProcessorErrors.POJO_FIELD_HAS_DUPLICATE_COLUMN_NAME
@@ -871,7 +871,7 @@
             assertThat(pojo5, sameInstance(pojo4))
 
             val type = invocation.context.COMMON_TYPES.STRING
-            val mockElement = mock(XVariableElement::class.java)
+            val mockElement = mock(XFieldElement::class.java)
             doReturn(type).`when`(mockElement).type
             val fakeField = Field(
                     element = mockElement,
diff --git a/room/compiler/src/test/kotlin/androidx/room/testing/test_util.kt b/room/compiler/src/test/kotlin/androidx/room/testing/test_util.kt
index 218215b..6976a76 100644
--- a/room/compiler/src/test/kotlin/androidx/room/testing/test_util.kt
+++ b/room/compiler/src/test/kotlin/androidx/room/testing/test_util.kt
@@ -16,6 +16,9 @@
 
 import androidx.room.DatabaseView
 import androidx.room.Entity
+import androidx.room.compiler.processing.XElement
+import androidx.room.compiler.processing.XFieldElement
+import androidx.room.compiler.processing.XType
 import androidx.room.ext.GuavaUtilConcurrentTypeNames
 import androidx.room.ext.KotlinTypeNames
 import androidx.room.ext.LifecyclesTypeNames
@@ -26,9 +29,6 @@
 import androidx.room.ext.RoomRxJava3TypeNames
 import androidx.room.ext.RxJava2TypeNames
 import androidx.room.ext.RxJava3TypeNames
-import androidx.room.compiler.processing.XElement
-import androidx.room.compiler.processing.XType
-import androidx.room.compiler.processing.XVariableElement
 import androidx.room.processor.DatabaseViewProcessor
 import androidx.room.processor.TableEntityProcessor
 import androidx.room.solver.CodeGenScope
@@ -238,8 +238,8 @@
  * Create mocks of [XElement] and [XType] so that they can be used for instantiating a fake
  * [androidx.room.vo.Field].
  */
-fun mockElementAndType(): Pair<XVariableElement, XType> {
-    val element = mock(XVariableElement::class.java)
+fun mockElementAndType(): Pair<XFieldElement, XType> {
+    val element = mock(XFieldElement::class.java)
     val type = mock(XType::class.java)
     doReturn(type).`when`(element).type
     return element to type
diff --git a/room/compiler/src/test/kotlin/androidx/room/verifier/DatabaseVerifierTest.kt b/room/compiler/src/test/kotlin/androidx/room/verifier/DatabaseVerifierTest.kt
index e8eae61..d4e059a 100644
--- a/room/compiler/src/test/kotlin/androidx/room/verifier/DatabaseVerifierTest.kt
+++ b/room/compiler/src/test/kotlin/androidx/room/verifier/DatabaseVerifierTest.kt
@@ -16,15 +16,15 @@
 
 package androidx.room.verifier
 
-import androidx.room.parser.Collate
-import androidx.room.parser.SQLTypeAffinity
-import androidx.room.parser.SqlParser
 import androidx.room.compiler.processing.XConstructorElement
 import androidx.room.compiler.processing.XDeclaredType
 import androidx.room.compiler.processing.XElement
+import androidx.room.compiler.processing.XFieldElement
 import androidx.room.compiler.processing.XType
 import androidx.room.compiler.processing.XTypeElement
-import androidx.room.compiler.processing.XVariableElement
+import androidx.room.parser.Collate
+import androidx.room.parser.SQLTypeAffinity
+import androidx.room.parser.SqlParser
 import androidx.room.processor.Context
 import androidx.room.testing.TestInvocation
 import androidx.room.vo.CallType
@@ -322,7 +322,7 @@
         affinity: SQLTypeAffinity,
         defaultValue: String? = null
     ): Field {
-        val element = mock(XVariableElement::class.java)
+        val element = mock(XFieldElement::class.java)
         doReturn(type).`when`(element).type
         val f = Field(
             element = element,