Model top level functions and properties
This CL adds support for top level functions/properties in KSP.
KSP does not generate synthetic class for files that include top
level methods or properites.
see: https://github.com/google/ksp/issues/396
For XProcessing, i decided the follow through and not create a fake
XTypeElement for them. Instead, this CL introduces a new XElement
type called XMemberContainer. This interface defines two properties:
className:ClassName and type:XType.
ClassName is mandatory whereas XType is optional (to denote that it
does not have an accessible type in KSP but ClassName can be accessed
for code generation).
This was enough to make the rest of the codebase happy.
For Room, I also removed `XMethod/FieldElement.requireEnclosingTypeElement`
as we didn't really need it once we have className.
XMemberContainer might be extended to provide access to more declarations
but we don't yet have a use case for that.
By not modeling fake XTypeElements, we avoid creating a fake XType for it,
which prevents lots of pitfalls since the type does not really exist in
kotlin world.
Bug: 160322705
Fixes: 184526463
Test: XRoundEnvTest, TopLevelMembersTest
Change-Id: Iea60d2587c9373a96a56f7721d5ea2782b66ba2e
diff --git a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/MethodCollector.kt b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/MethodCollector.kt
index e3be1a9..7cac32a 100644
--- a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/MethodCollector.kt
+++ b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/MethodCollector.kt
@@ -78,7 +78,7 @@
return false
}
// check package
- return packageName == other.requireEnclosingTypeElement().packageName
+ return packageName == other.enclosingElement.className.packageName()
}
}
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 3df684f..0bc4dd0 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
@@ -25,9 +25,15 @@
/**
* The element that declared this executable.
*
- * @see requireEnclosingTypeElement
+ * For methods declared as top level functions in Kotlin:
+ * * When running with KAPT, the value will be an [XTypeElement].
+ * * When running with KSP, if this function is coming from the classpath, the value will
+ * be an [XTypeElement].
+ * * When running with KSP, if this function is in source, the value will **NOT** be an
+ * [XTypeElement]. If you need the generated synthetic java class name, you can use
+ * [XMemberContainer.className] property.
*/
- val enclosingElement: XElement
+ val enclosingElement: XMemberContainer
/**
* The list of parameters that should be passed into this method.
*
@@ -39,12 +45,3 @@
*/
fun isVarArgs(): Boolean
}
-
-/**
- * Checks the enclosing element is a TypeElement and returns it, otherwise,
- * throws [IllegalStateException].
- */
-fun XExecutableElement.requireEnclosingTypeElement(): XTypeElement {
- return enclosingElement as? XTypeElement
- ?: error("Required enclosing type element for $this but found $enclosingElement")
-}
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
index bb3701a..6d9540f 100644
--- 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
@@ -22,16 +22,18 @@
interface XFieldElement : XVariableElement, XHasModifiers {
/**
* The element that declared this field.
+ * For fields declared in classes, this will be an [XTypeElement].
*
- * @see requireEnclosingTypeElement
+ * For fields declared as top level properties in Kotlin:
+ * * When running with KAPT, the value will be an [XTypeElement].
+ * * When running with KSP, if this property is coming from the classpath, the value will
+ * be an [XTypeElement].
+ * * When running with KSP, if this property is in source, the value will **NOT** be an
+ * [XTypeElement]. If you need the generated synthetic java class name, you can use
+ * [XMemberContainer.className] property.
*/
- val enclosingElement: XElement
+ val enclosingElement: XMemberContainer
override val fallbackLocationText: String
get() = "$name in ${enclosingElement.fallbackLocationText}"
}
-
-fun XFieldElement.requireEnclosingTypeElement(): XTypeElement {
- return enclosingElement as? XTypeElement
- ?: error("Required enclosing type element for $this but found $enclosingElement")
-}
\ No newline at end of file
diff --git a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/XMemberContainer.kt b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/XMemberContainer.kt
new file mode 100644
index 0000000..86aa1d2
--- /dev/null
+++ b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/XMemberContainer.kt
@@ -0,0 +1,39 @@
+/*
+ * 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.compiler.processing
+
+import com.squareup.javapoet.ClassName
+
+/**
+ * Common interface for elements that can contain methods and properties.
+ *
+ * This is especially important for handling top level methods / properties in KSP where the
+ * synthetic container class does not exist
+ */
+interface XMemberContainer : XElement {
+ /**
+ * The JVM ClassName for this container.
+ * For top level members of a Kotlin file, you can use this [className] for code generation.
+ */
+ val className: ClassName
+
+ /**
+ * The [XType] for the container if this is an [XTypeElement] otherwise `null` if a type
+ * representing this container does not exist (e.g. a top level Kotlin source file)
+ */
+ val type: XType?
+}
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 76e1e96..5109aff 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,7 +18,7 @@
import com.squareup.javapoet.ClassName
-interface XTypeElement : XHasModifiers, XElement {
+interface XTypeElement : XHasModifiers, XElement, XMemberContainer {
/**
* The qualified name of the Class/Interface.
*/
@@ -39,7 +39,7 @@
/**
* The type represented by this [XTypeElement].
*/
- val type: XType
+ override val type: XType
/**
* The super type of this element if it represents a class.
@@ -49,7 +49,7 @@
/**
* Javapoet [ClassName] of the type.
*/
- val className: ClassName
+ override val className: ClassName
/**
* The [XTypeElement] that contains this [XTypeElement] if it is an inner class/interface.
diff --git a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KSAsMemberOf.kt b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KSAsMemberOf.kt
index 7e84d7c..37a3569 100644
--- a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KSAsMemberOf.kt
+++ b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KSAsMemberOf.kt
@@ -25,13 +25,16 @@
/**
* Returns the type of a property as if it is member of the given [ksType].
*/
-internal fun KSPropertyDeclaration.typeAsMemberOf(resolver: Resolver, ksType: KSType): KSType {
+internal fun KSPropertyDeclaration.typeAsMemberOf(resolver: Resolver, ksType: KSType?): KSType {
val resolved = type.resolve()
if (isStatic()) {
// calling as member with a static would throw as it might be a member of the companion
// object
return resolved
}
+ if (ksType == null) {
+ return resolved
+ }
// see: https://github.com/google/ksp/issues/107
// as member of might lose the `isError` information hence we should check before calling
// asMemberOf.
@@ -47,7 +50,7 @@
internal fun KSValueParameter.typeAsMemberOf(
resolver: Resolver,
functionDeclaration: KSFunctionDeclaration,
- ksType: KSType
+ ksType: KSType?
): KSType {
val resolved = type.resolve()
if (functionDeclaration.isStatic()) {
@@ -61,6 +64,9 @@
// asMemberOf.
return resolved
}
+ if (ksType == null) {
+ return resolved
+ }
val asMember = resolver.asMemberOf(
function = functionDeclaration,
containing = ksType
@@ -73,11 +79,12 @@
internal fun KSFunctionDeclaration.returnTypeAsMemberOf(
resolver: Resolver,
- ksType: KSType
+ ksType: KSType?
): KSType {
val resolved = returnType?.resolve()
return when {
resolved == null -> null
+ ksType == null -> resolved
resolved.isError -> resolved
isStatic() -> {
// calling as member with a static would throw as it might be a member of the companion
diff --git a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KSDeclarationExt.kt b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KSDeclarationExt.kt
index 054c840..2b59a34 100644
--- a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KSDeclarationExt.kt
+++ b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KSDeclarationExt.kt
@@ -18,6 +18,9 @@
import com.google.devtools.ksp.symbol.KSClassDeclaration
import com.google.devtools.ksp.symbol.KSDeclaration
+import com.google.devtools.ksp.symbol.KSFunctionDeclaration
+import com.google.devtools.ksp.symbol.KSPropertyAccessor
+import com.google.devtools.ksp.symbol.KSPropertyDeclaration
import com.google.devtools.ksp.symbol.Modifier
/**
@@ -25,8 +28,10 @@
* be found.
* @see [findEnclosingAncestorClassDeclaration]
*/
-internal fun KSDeclaration.requireEnclosingTypeElement(env: KspProcessingEnv): KspTypeElement {
- return checkNotNull(findEnclosingTypeElement(env)) {
+internal fun KSDeclaration.requireEnclosingMemberContainer(
+ env: KspProcessingEnv
+): KspMemberContainer {
+ return checkNotNull(findEnclosingMemberContainer(env)) {
"Cannot find required enclosing type for $this"
}
}
@@ -37,13 +42,17 @@
* Node that this is not necessarily the parent declaration. e.g. when a property is declared in
* a constructor, its containing type is actual two levels up.
*/
-internal fun KSDeclaration.findEnclosingTypeElement(env: KspProcessingEnv): KspTypeElement? {
+internal fun KSDeclaration.findEnclosingMemberContainer(
+ env: KspProcessingEnv
+): KspMemberContainer? {
return findEnclosingAncestorClassDeclaration()?.let {
env.wrapClassDeclaration(it)
+ } ?: this.containingFile?.let {
+ env.wrapKSFile(it)
}
}
-internal fun KSDeclaration.findEnclosingAncestorClassDeclaration(): KSClassDeclaration? {
+private fun KSDeclaration.findEnclosingAncestorClassDeclaration(): KSClassDeclaration? {
var parent = parentDeclaration
while (parent != null && parent !is KSClassDeclaration) {
parent = parent.parentDeclaration
@@ -52,7 +61,13 @@
}
internal fun KSDeclaration.isStatic(): Boolean {
- return modifiers.contains(Modifier.JAVA_STATIC) || hasJvmStaticAnnotation()
+ return modifiers.contains(Modifier.JAVA_STATIC) || hasJvmStaticAnnotation() ||
+ when (this) {
+ is KSPropertyAccessor -> this.receiver.findEnclosingAncestorClassDeclaration() == null
+ is KSPropertyDeclaration -> this.findEnclosingAncestorClassDeclaration() == null
+ is KSFunctionDeclaration -> this.findEnclosingAncestorClassDeclaration() == null
+ else -> false
+ }
}
internal fun KSDeclaration.isTransient(): Boolean {
diff --git a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspAnnotated.kt b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspAnnotated.kt
index 180ceec..708e243 100644
--- a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspAnnotated.kt
+++ b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspAnnotated.kt
@@ -112,11 +112,16 @@
fun accept(annotation: KSAnnotation): Boolean
private class Impl(
- val acceptedTarget: AnnotationUseSiteTarget
+ val acceptedTarget: AnnotationUseSiteTarget,
+ private val acceptNoTarget: Boolean = true,
) : UseSiteFilter {
override fun accept(annotation: KSAnnotation): Boolean {
val target = annotation.useSiteTarget
- return target == null || acceptedTarget == target
+ return if (target == null) {
+ acceptNoTarget
+ } else {
+ acceptedTarget == target
+ }
}
}
@@ -132,6 +137,10 @@
val NO_USE_SITE_OR_GETTER: UseSiteFilter = Impl(AnnotationUseSiteTarget.GET)
val NO_USE_SITE_OR_SETTER: UseSiteFilter = Impl(AnnotationUseSiteTarget.SET)
val NO_USE_SITE_OR_SET_PARAM: UseSiteFilter = Impl(AnnotationUseSiteTarget.SETPARAM)
+ val FILE: UseSiteFilter = Impl(
+ acceptedTarget = AnnotationUseSiteTarget.FILE,
+ acceptNoTarget = false
+ )
}
}
diff --git a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspConstructorElement.kt b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspConstructorElement.kt
index 7417435..fb3ff2c 100644
--- a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspConstructorElement.kt
+++ b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspConstructorElement.kt
@@ -21,11 +21,16 @@
internal class KspConstructorElement(
env: KspProcessingEnv,
- containing: KspTypeElement,
+ override val containing: KspTypeElement,
declaration: KSFunctionDeclaration
) : KspExecutableElement(
env = env,
containing = containing,
declaration = declaration
),
- XConstructorElement
+ XConstructorElement {
+ override val enclosingElement: KspTypeElement by lazy {
+ declaration.requireEnclosingMemberContainer(env) as? KspTypeElement
+ ?: error("Constructor parent must be a type element $this")
+ }
+}
diff --git a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspExecutableElement.kt b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspExecutableElement.kt
index 3d3b83a..cb4ee5f 100644
--- a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspExecutableElement.kt
+++ b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspExecutableElement.kt
@@ -20,7 +20,6 @@
import androidx.room.compiler.processing.XExecutableElement
import androidx.room.compiler.processing.XExecutableParameterElement
import androidx.room.compiler.processing.XHasModifiers
-import androidx.room.compiler.processing.XTypeElement
import androidx.room.compiler.processing.ksp.KspAnnotated.UseSiteFilter.Companion.NO_USE_SITE
import com.google.devtools.ksp.isConstructor
import com.google.devtools.ksp.symbol.KSFunctionDeclaration
@@ -28,7 +27,7 @@
internal abstract class KspExecutableElement(
env: KspProcessingEnv,
- val containing: KspTypeElement,
+ open val containing: KspMemberContainer,
override val declaration: KSFunctionDeclaration
) : KspElement(
env = env,
@@ -46,8 +45,8 @@
arrayOf(containing, declaration)
}
- override val enclosingElement: XTypeElement by lazy {
- declaration.requireEnclosingTypeElement(env)
+ override val enclosingElement: KspMemberContainer by lazy {
+ declaration.requireEnclosingMemberContainer(env)
}
override val parameters: List<XExecutableParameterElement> by lazy {
@@ -74,9 +73,9 @@
env: KspProcessingEnv,
declaration: KSFunctionDeclaration
): KspExecutableElement {
- val enclosingType = declaration.findEnclosingTypeElement(env)
+ val enclosingContainer = declaration.findEnclosingMemberContainer(env)
- checkNotNull(enclosingType) {
+ checkNotNull(enclosingContainer) {
"XProcessing does not currently support annotations on top level " +
"functions with KSP. Cannot process $declaration."
}
@@ -85,14 +84,16 @@
declaration.isConstructor() -> {
KspConstructorElement(
env = env,
- containing = enclosingType,
+ containing = enclosingContainer as? KspTypeElement ?: error(
+ "The container for $declaration should be a type element"
+ ),
declaration = declaration
)
}
else -> {
KspMethodElement.create(
env = env,
- containing = enclosingType,
+ containing = enclosingContainer,
declaration = declaration
)
}
diff --git a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspExecutableParameterElement.kt b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspExecutableParameterElement.kt
index 8d5f6ac..883efc3 100644
--- a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspExecutableParameterElement.kt
+++ b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspExecutableParameterElement.kt
@@ -40,7 +40,7 @@
parameter.typeAsMemberOf(
resolver = env.resolver,
functionDeclaration = method.declaration,
- ksType = method.containing.declaration.asStarProjectedType()
+ ksType = method.containing.type?.ksType
).let {
env.wrap(
originatingReference = parameter.type,
@@ -53,7 +53,7 @@
get() = "$name in ${method.fallbackLocationText}"
override fun asMemberOf(other: XType): KspType {
- if (method.containing.type.isSameType(other)) {
+ if (method.containing.type?.isSameType(other) != false) {
return type
}
check(other is KspType)
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 8955362..5418300 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
@@ -20,14 +20,13 @@
import androidx.room.compiler.processing.XFieldElement
import androidx.room.compiler.processing.XHasModifiers
import androidx.room.compiler.processing.XType
-import androidx.room.compiler.processing.XTypeElement
import androidx.room.compiler.processing.ksp.KspAnnotated.UseSiteFilter.Companion.NO_USE_SITE_OR_FIELD
import com.google.devtools.ksp.symbol.KSPropertyDeclaration
internal class KspFieldElement(
env: KspProcessingEnv,
override val declaration: KSPropertyDeclaration,
- val containing: KspTypeElement
+ val containing: KspMemberContainer
) : KspElement(env, declaration),
XFieldElement,
XHasModifiers by KspHasModifiers.create(declaration),
@@ -37,8 +36,8 @@
arrayOf(declaration, containing)
}
- override val enclosingElement: XTypeElement by lazy {
- declaration.requireEnclosingTypeElement(env)
+ override val enclosingElement: KspMemberContainer by lazy {
+ declaration.requireEnclosingMemberContainer(env)
}
override val name: String by lazy {
@@ -48,12 +47,12 @@
override val type: KspType by lazy {
env.wrap(
originatingReference = declaration.type,
- ksType = declaration.typeAsMemberOf(env.resolver, containing.type.ksType)
+ ksType = declaration.typeAsMemberOf(env.resolver, containing.type?.ksType)
)
}
override fun asMemberOf(other: XType): XType {
- if (containing.type.isSameType(other)) {
+ if (containing.type?.isSameType(other) != false) {
return type
}
check(other is KspType)
@@ -78,7 +77,7 @@
return KspFieldElement(
env = env,
declaration = declaration,
- containing = declaration.requireEnclosingTypeElement(env)
+ containing = declaration.requireEnclosingMemberContainer(env)
)
}
}
diff --git a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspFileMemberContainer.kt b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspFileMemberContainer.kt
new file mode 100644
index 0000000..9d91bb4
--- /dev/null
+++ b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspFileMemberContainer.kt
@@ -0,0 +1,72 @@
+/*
+ * 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.compiler.processing.ksp
+
+import androidx.room.compiler.processing.XAnnotated
+import com.google.devtools.ksp.symbol.AnnotationUseSiteTarget
+import com.google.devtools.ksp.symbol.KSDeclaration
+import com.google.devtools.ksp.symbol.KSFile
+import com.squareup.javapoet.ClassName
+
+/**
+ * [XMemberContainer] implementation for KSFiles.
+ */
+internal class KspFileMemberContainer(
+ private val env: KspProcessingEnv,
+ private val ksFile: KSFile
+) : KspMemberContainer,
+ XAnnotated by KspAnnotated.create(
+ env = env,
+ delegate = ksFile,
+ filter = KspAnnotated.UseSiteFilter.FILE
+ ) {
+ override val type: KspType?
+ get() = null
+ override val declaration: KSDeclaration?
+ get() = null
+ override val className: ClassName by lazy {
+
+ val pkgName = ksFile.packageName.asString().let {
+ if (it == "<root>") {
+ ""
+ } else {
+ it
+ }
+ }
+ ClassName.get(
+ pkgName, ksFile.findClassName()
+ )
+ }
+
+ override fun kindName(): String {
+ return "file"
+ }
+
+ override val fallbackLocationText: String = ksFile.filePath
+
+ companion object {
+ private fun KSFile.findClassName(): String {
+ return annotations.firstOrNull {
+ it.useSiteTarget == AnnotationUseSiteTarget.FILE &&
+ it.annotationType.resolve().declaration.qualifiedName?.asString() ==
+ JvmName::class.qualifiedName
+ }?.arguments?.firstOrNull {
+ it.name?.asString() == "name"
+ }?.value?.toString() ?: fileName.replace(".kt", "Kt")
+ }
+ }
+}
\ No newline at end of file
diff --git a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspMemberContainer.kt b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspMemberContainer.kt
new file mode 100644
index 0000000..a6d0a79
--- /dev/null
+++ b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspMemberContainer.kt
@@ -0,0 +1,25 @@
+/*
+ * 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.compiler.processing.ksp
+
+import androidx.room.compiler.processing.XMemberContainer
+import com.google.devtools.ksp.symbol.KSDeclaration
+
+internal interface KspMemberContainer : XMemberContainer {
+ override val type: KspType?
+ val declaration: KSDeclaration?
+}
\ No newline at end of file
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 1303247..c4df7a0 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
@@ -30,7 +30,7 @@
internal sealed class KspMethodElement(
env: KspProcessingEnv,
- containing: KspTypeElement,
+ containing: KspMemberContainer,
declaration: KSFunctionDeclaration
) : KspExecutableElement(
env = env,
@@ -90,7 +90,7 @@
private class KspNormalMethodElement(
env: KspProcessingEnv,
- containing: KspTypeElement,
+ containing: KspMemberContainer,
declaration: KSFunctionDeclaration
) : KspMethodElement(
env, containing, declaration
@@ -103,7 +103,7 @@
env.wrap(
ksType = declaration.returnTypeAsMemberOf(
resolver = env.resolver,
- ksType = containing.type.ksType
+ ksType = containing.type?.ksType
),
originatingReference = checkNotNull(overridee?.returnType ?: declaration.returnType)
)
@@ -113,7 +113,7 @@
private class KspSuspendMethodElement(
env: KspProcessingEnv,
- containing: KspTypeElement,
+ containing: KspMemberContainer,
declaration: KSFunctionDeclaration
) : KspMethodElement(
env, containing, declaration
@@ -137,7 +137,7 @@
companion object {
fun create(
env: KspProcessingEnv,
- containing: KspTypeElement,
+ containing: KspMemberContainer,
declaration: KSFunctionDeclaration
): KspMethodElement {
return if (declaration.modifiers.contains(Modifier.SUSPEND)) {
diff --git a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspMethodType.kt b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspMethodType.kt
index 1b84172..ec69fdd 100644
--- a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspMethodType.kt
+++ b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspMethodType.kt
@@ -24,11 +24,17 @@
internal sealed class KspMethodType(
val env: KspProcessingEnv,
val origin: KspMethodElement,
- val containing: KspType
+ val containing: KspType?
) : XMethodType {
override val parameterTypes: List<XType> by lazy {
- origin.parameters.map {
- it.asMemberOf(containing)
+ if (containing == null) {
+ origin.parameters.map {
+ it.type
+ }
+ } else {
+ origin.parameters.map {
+ it.asMemberOf(containing)
+ }
}
}
@@ -56,7 +62,7 @@
private class KspNormalMethodType(
env: KspProcessingEnv,
origin: KspMethodElement,
- containing: KspType
+ containing: KspType?
) : KspMethodType(env, origin, containing) {
override val returnType: XType by lazy {
// b/160258066
@@ -67,7 +73,7 @@
originatingReference = (overridee?.returnType ?: origin.declaration.returnType)!!,
ksType = origin.declaration.returnTypeAsMemberOf(
resolver = env.resolver,
- ksType = containing.ksType
+ ksType = containing?.ksType
)
)
}
@@ -76,7 +82,7 @@
private class KspSuspendMethodType(
env: KspProcessingEnv,
origin: KspMethodElement,
- containing: KspType
+ containing: KspType?
) : KspMethodType(env, origin, containing), XSuspendMethodType {
override val returnType: XType
// suspend functions always return Any?, no need to call asMemberOf
@@ -87,7 +93,7 @@
return env.wrap(
ksType = origin.declaration.returnTypeAsMemberOf(
resolver = env.resolver,
- ksType = containing.ksType
+ ksType = containing?.ksType
),
allowPrimitives = false
)
@@ -98,7 +104,7 @@
fun create(
env: KspProcessingEnv,
origin: KspMethodElement,
- containing: KspType
+ containing: KspType?
) = if (origin.isSuspendFunction()) {
KspSuspendMethodType(env, origin, containing)
} else {
diff --git a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspProcessingEnv.kt b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspProcessingEnv.kt
index febd6cc..499634e 100644
--- a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspProcessingEnv.kt
+++ b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/KspProcessingEnv.kt
@@ -27,6 +27,7 @@
import com.google.devtools.ksp.processing.KSPLogger
import com.google.devtools.ksp.processing.Resolver
import com.google.devtools.ksp.symbol.KSClassDeclaration
+import com.google.devtools.ksp.symbol.KSFile
import com.google.devtools.ksp.symbol.KSType
import com.google.devtools.ksp.symbol.KSTypeAlias
import com.google.devtools.ksp.symbol.KSTypeArgument
@@ -42,6 +43,7 @@
val resolver: Resolver
) : XProcessingEnv {
override val backend: XProcessingEnv.Backend = XProcessingEnv.Backend.KSP
+ private val ksFileMemberContainers = mutableMapOf<KSFile, KspFileMemberContainer>()
private val typeElementStore =
XTypeElementStore(
@@ -212,6 +214,15 @@
return typeElementStore[declaration]
}
+ fun wrapKSFile(file: KSFile): KspMemberContainer {
+ return ksFileMemberContainers.getOrPut(file) {
+ KspFileMemberContainer(
+ env = this,
+ ksFile = file
+ )
+ }
+ }
+
class CommonTypes(resolver: Resolver) {
val nullableInt by lazy {
resolver.builtIns.intType.makeNullable()
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 f4d111c..c7f17c6 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
@@ -47,7 +47,8 @@
) : KspElement(env, declaration),
XTypeElement,
XHasModifiers by KspHasModifiers.create(declaration),
- XAnnotated by KspAnnotated.create(env, declaration, NO_USE_SITE) {
+ XAnnotated by KspAnnotated.create(env, declaration, NO_USE_SITE),
+ KspMemberContainer {
/**
* The true origin of this class file. This may not match `declaration.origin` when declaration
@@ -68,7 +69,8 @@
}
override val enclosingTypeElement: XTypeElement? by lazy {
- declaration.findEnclosingTypeElement(env)
+ // if it is a file, don't return it
+ declaration.findEnclosingMemberContainer(env) as? XTypeElement
}
override val equalityItems: Array<out Any?> by lazy {
diff --git a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/OverrideVarianceResolver.kt b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/OverrideVarianceResolver.kt
index 9453e19..505ec1f 100644
--- a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/OverrideVarianceResolver.kt
+++ b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/OverrideVarianceResolver.kt
@@ -96,7 +96,7 @@
containing = env.wrapClassDeclaration(declaredIn),
declaration = funDeclaration.findOverridee() ?: funDeclaration
)
- val containing = overrideeElm.enclosingElement.type as? KspType ?: return null
+ val containing = overrideeElm.enclosingElement.type ?: return null
return KspMethodType.create(
env = env,
origin = overrideeElm,
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 25613b0..7ad376f 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
@@ -20,6 +20,7 @@
import androidx.room.compiler.processing.XEquality
import androidx.room.compiler.processing.XExecutableParameterElement
import androidx.room.compiler.processing.XHasModifiers
+import androidx.room.compiler.processing.XMemberContainer
import androidx.room.compiler.processing.XMethodElement
import androidx.room.compiler.processing.XMethodType
import androidx.room.compiler.processing.XType
@@ -32,7 +33,7 @@
import androidx.room.compiler.processing.ksp.KspHasModifiers
import androidx.room.compiler.processing.ksp.KspProcessingEnv
import androidx.room.compiler.processing.ksp.KspTypeElement
-import androidx.room.compiler.processing.ksp.findEnclosingTypeElement
+import androidx.room.compiler.processing.ksp.findEnclosingMemberContainer
import androidx.room.compiler.processing.ksp.overrides
import com.google.devtools.ksp.KspExperimental
import com.google.devtools.ksp.symbol.KSPropertyAccessor
@@ -67,7 +68,7 @@
final override fun isSuspendFunction() = false
- final override val enclosingElement: XTypeElement
+ final override val enclosingElement: XMemberContainer
get() = this.field.enclosingElement
final override fun isVarArgs() = false
@@ -248,7 +249,7 @@
env: KspProcessingEnv,
propertyAccessor: KSPropertyAccessor
): KspSyntheticPropertyMethodElement {
- val enclosingType = propertyAccessor.receiver.findEnclosingTypeElement(env)
+ val enclosingType = propertyAccessor.receiver.findEnclosingMemberContainer(env)
checkNotNull(enclosingType) {
"XProcessing does not currently support annotations on top level " +
diff --git a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/synthetic/KspSyntheticPropertyMethodType.kt b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/synthetic/KspSyntheticPropertyMethodType.kt
index b8c5bd5..8d442b5 100644
--- a/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/synthetic/KspSyntheticPropertyMethodType.kt
+++ b/room/compiler-processing/src/main/java/androidx/room/compiler/processing/ksp/synthetic/KspSyntheticPropertyMethodType.kt
@@ -25,12 +25,18 @@
*/
internal sealed class KspSyntheticPropertyMethodType(
val origin: KspSyntheticPropertyMethodElement,
- val containing: XType
+ val containing: XType?
) : XMethodType {
override val parameterTypes: List<XType> by lazy {
- origin.parameters.map {
- it.asMemberOf(containing)
+ if (containing == null) {
+ origin.parameters.map {
+ it.type
+ }
+ } else {
+ origin.parameters.map {
+ it.asMemberOf(containing)
+ }
}
}
@@ -40,7 +46,7 @@
companion object {
fun create(
element: KspSyntheticPropertyMethodElement,
- container: XType
+ container: XType?
): XMethodType {
return when (element) {
is KspSyntheticPropertyMethodElement.Getter ->
@@ -59,19 +65,23 @@
private class Getter(
origin: KspSyntheticPropertyMethodElement.Getter,
- containingType: XType
+ containingType: XType?
) : KspSyntheticPropertyMethodType(
origin = origin,
containing = containingType
) {
override val returnType: XType by lazy {
- origin.field.asMemberOf(containingType)
+ if (containingType == null) {
+ origin.field.type
+ } else {
+ origin.field.asMemberOf(containingType)
+ }
}
}
private class Setter(
origin: KspSyntheticPropertyMethodElement.Setter,
- containingType: XType
+ containingType: XType?
) : KspSyntheticPropertyMethodType(
origin = origin,
containing = containingType
diff --git a/room/compiler-processing/src/test/java/androidx/room/compiler/processing/TopLevelMembersTest.kt b/room/compiler-processing/src/test/java/androidx/room/compiler/processing/TopLevelMembersTest.kt
new file mode 100644
index 0000000..5a38d57
--- /dev/null
+++ b/room/compiler-processing/src/test/java/androidx/room/compiler/processing/TopLevelMembersTest.kt
@@ -0,0 +1,93 @@
+/*
+ * 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.compiler.processing
+
+import androidx.room.compiler.processing.ksp.KspExecutableElement
+import androidx.room.compiler.processing.ksp.KspFieldElement
+import androidx.room.compiler.processing.util.Source
+import androidx.room.compiler.processing.util.compileFiles
+import androidx.room.compiler.processing.util.kspProcessingEnv
+import androidx.room.compiler.processing.util.kspResolver
+import androidx.room.compiler.processing.util.runKspTest
+import com.google.common.truth.Truth.assertThat
+import com.google.devtools.ksp.KspExperimental
+import com.google.devtools.ksp.symbol.KSFunctionDeclaration
+import com.google.devtools.ksp.symbol.KSPropertyDeclaration
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@RunWith(JUnit4::class)
+@OptIn(KspExperimental::class)
+class TopLevelMembersTest {
+ @Test
+ fun topLevelInDependency() {
+ val libSrc = Source.kotlin(
+ "lib/Foo.kt",
+ """
+ package lib
+ fun topLevelFun() {
+ }
+ val topLevelVal: String = ""
+ var topLevelVar: String = ""
+ """.trimIndent()
+ )
+ val classpath = compileFiles(listOf(libSrc))
+ val appSrc = Source.kotlin(
+ "app/Foo.kt",
+ """
+ package app
+ fun topLevelFun() {
+ }
+ val topLevelVal: String = ""
+ var topLevelVar: String = ""
+ """.trimIndent()
+ )
+ runKspTest(
+ sources = listOf(appSrc),
+ classpath = listOf(classpath)
+ ) { invocation ->
+ // TODO add lib package here once Room updates to a version that includes the
+ // https://github.com/google/ksp/issues/396 fix (1.5.0-1.0.0-alpha09)
+ val declarations = invocation.kspResolver.getDeclarationsFromPackage("app")
+ declarations.filterIsInstance<KSFunctionDeclaration>()
+ .toList().let { methods ->
+ assertThat(methods).hasSize(1)
+ methods.forEach { method ->
+ val element = KspExecutableElement.create(
+ env = invocation.kspProcessingEnv,
+ declaration = method
+ )
+ assertThat(element.containing.isTypeElement()).isFalse()
+ assertThat(element.isStatic()).isTrue()
+ }
+ }
+ declarations.filterIsInstance<KSPropertyDeclaration>()
+ .toList().let { properties ->
+ assertThat(properties).hasSize(2)
+ properties.forEach {
+ val element = KspFieldElement.create(
+ env = invocation.kspProcessingEnv,
+ declaration = it
+ )
+ assertThat(element.containing.isTypeElement()).isFalse()
+ assertThat(element.isStatic()).isTrue()
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/room/compiler-processing/src/test/java/androidx/room/compiler/processing/XRoundEnvTest.kt b/room/compiler-processing/src/test/java/androidx/room/compiler/processing/XRoundEnvTest.kt
index 30c7953..3b79246 100644
--- a/room/compiler-processing/src/test/java/androidx/room/compiler/processing/XRoundEnvTest.kt
+++ b/room/compiler-processing/src/test/java/androidx/room/compiler/processing/XRoundEnvTest.kt
@@ -21,8 +21,11 @@
import androidx.room.compiler.processing.util.getDeclaredMethod
import androidx.room.compiler.processing.util.getField
import androidx.room.compiler.processing.util.getMethod
+import androidx.room.compiler.processing.util.runKspTest
import androidx.room.compiler.processing.util.runProcessorTest
import com.google.common.truth.Truth.assertThat
+import com.squareup.javapoet.ClassName
+import com.squareup.javapoet.TypeName
import org.junit.Test
class XRoundEnvTest {
@@ -138,39 +141,16 @@
)
runProcessorTest(listOf(source)) { testInvocation ->
- if (testInvocation.isKsp) {
- // Currently not supported
- // https://issuetracker.google.com/issues/184526463
- val exception = try {
- testInvocation.roundEnv.getElementsAnnotatedWith(
- TopLevelAnnotation::class
- )
- null
- } catch (e: Throwable) {
- e
- }
-
- assertThat(exception).isNotNull()
- assertThat(exception)
- .hasMessageThat()
- .contains(
- "XProcessing does not currently support annotations on top level functions"
- )
- } else {
-
- val annotatedElements = testInvocation.roundEnv.getElementsAnnotatedWith(
- TopLevelAnnotation::class
- )
-
- val targetElement = testInvocation.processingEnv.requireTypeElement("BazKt")
-
- assertThat(
- annotatedElements
- ).apply {
- hasSize(1)
- contains(targetElement.getDeclaredMethod("myFun"))
- }
- }
+ val annotatedElements = testInvocation.roundEnv.getElementsAnnotatedWith(
+ TopLevelAnnotation::class
+ )
+ assertThat(annotatedElements).hasSize(1)
+ val subject = annotatedElements.filterIsInstance<XMethodElement>().first()
+ assertThat(subject.name).isEqualTo("myFun")
+ assertThat(subject.enclosingElement.className).isEqualTo(
+ ClassName.get("", "BazKt")
+ )
+ assertThat(subject.isStatic()).isTrue()
}
}
@@ -179,51 +159,66 @@
val source = Source.kotlin(
"Baz.kt",
"""
+ @file:JvmName("MyCustomClass")
+ package foo.bar
import androidx.room.compiler.processing.XRoundEnvTest.TopLevelAnnotation
@get:TopLevelAnnotation
+ var myPropertyGetter: Int = 0
+ @set:TopLevelAnnotation
+ var myPropertySetter: Int = 0
+ @field:TopLevelAnnotation
var myProperty: Int = 0
""".trimIndent()
)
- runProcessorTest(listOf(source)) { testInvocation ->
- if (testInvocation.isKsp) {
- // Currently not supported
- // https://issuetracker.google.com/issues/184526463
- val exception = try {
- testInvocation.roundEnv.getElementsAnnotatedWith(
- TopLevelAnnotation::class
- )
- null
- } catch (e: Throwable) {
- e
+ runKspTest(listOf(source)) { testInvocation ->
+ val annotatedElements = testInvocation.roundEnv.getElementsAnnotatedWith(
+ TopLevelAnnotation::class
+ )
+ assertThat(annotatedElements).hasSize(3)
+ val byName = annotatedElements.associateBy {
+ when (it) {
+ is XMethodElement -> it.name
+ is XFieldElement -> it.name
+ else -> error("unexpected type $it")
}
-
- assertThat(exception).isNotNull()
- assertThat(exception)
- .hasMessageThat()
- .contains(
- "XProcessing does not currently support annotations on top level properties"
- )
- } else {
-
- val annotatedElements = testInvocation.roundEnv.getElementsAnnotatedWith(
- TopLevelAnnotation::class
+ }
+ val containerClassName = ClassName.get("foo.bar", "MyCustomClass")
+ assertThat(byName.keys).containsExactly(
+ "getMyPropertyGetter",
+ "setMyPropertySetter",
+ "myProperty"
+ )
+ (byName["getMyPropertyGetter"] as XMethodElement).let {
+ assertThat(it.returnType.typeName).isEqualTo(TypeName.INT)
+ assertThat(it.parameters).hasSize(0)
+ assertThat(it.enclosingElement.className).isEqualTo(
+ containerClassName
)
-
- val targetElement = testInvocation.processingEnv.requireTypeElement("BazKt")
-
- assertThat(
- annotatedElements
- ).apply {
- hasSize(1)
- contains(targetElement.getDeclaredMethod("getMyProperty"))
- }
+ assertThat(it.isStatic()).isTrue()
+ }
+ (byName["setMyPropertySetter"] as XMethodElement).let {
+ assertThat(it.returnType.typeName).isEqualTo(TypeName.VOID)
+ assertThat(it.parameters).hasSize(1)
+ assertThat(it.parameters.first().type.typeName).isEqualTo(TypeName.INT)
+ assertThat(it.enclosingElement.className).isEqualTo(
+ containerClassName
+ )
+ assertThat(it.isStatic()).isTrue()
+ }
+ (byName["myProperty"] as XFieldElement).let {
+ assertThat(it.type.typeName).isEqualTo(TypeName.INT)
+ assertThat(it.enclosingElement.className).isEqualTo(
+ containerClassName
+ )
+ assertThat(it.isStatic()).isTrue()
}
}
}
annotation class TopLevelAnnotation
+ @Suppress("unused") // used in tests
@Target(AnnotationTarget.PROPERTY)
annotation class PropertyAnnotation
}
diff --git a/room/compiler-processing/src/test/java/androidx/room/compiler/processing/util/XTestInvocationExt.kt b/room/compiler-processing/src/test/java/androidx/room/compiler/processing/util/XTestInvocationExt.kt
index 1e24f10..b98e232 100644
--- a/room/compiler-processing/src/test/java/androidx/room/compiler/processing/util/XTestInvocationExt.kt
+++ b/room/compiler-processing/src/test/java/androidx/room/compiler/processing/util/XTestInvocationExt.kt
@@ -22,6 +22,9 @@
import javax.lang.model.util.Elements
import javax.lang.model.util.Types
+internal val XTestInvocation.kspProcessingEnv: KspProcessingEnv
+ get() = (processingEnv as KspProcessingEnv)
+
val XTestInvocation.kspResolver: Resolver
get() = (processingEnv as KspProcessingEnv).resolver
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 de7ea10..855dc4d 100644
--- a/room/compiler/src/main/kotlin/androidx/room/processor/DatabaseProcessor.kt
+++ b/room/compiler/src/main/kotlin/androidx/room/processor/DatabaseProcessor.kt
@@ -22,7 +22,6 @@
import androidx.room.compiler.processing.XElement
import androidx.room.compiler.processing.XType
import androidx.room.compiler.processing.XTypeElement
-import androidx.room.compiler.processing.requireEnclosingTypeElement
import androidx.room.ext.RoomTypeNames
import androidx.room.migration.bundle.DatabaseBundle
import androidx.room.migration.bundle.SchemaBundle
@@ -91,7 +90,7 @@
it.isAbstract()
}.filterNot {
// remove methods that belong to room
- it.requireEnclosingTypeElement().className == RoomTypeNames.ROOM_DB
+ it.enclosingElement.className == RoomTypeNames.ROOM_DB
}.mapNotNull { executable ->
// TODO when we add support for non Dao return types (e.g. database), this code needs
// to change
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 8e1e745..030e56f 100644
--- a/room/compiler/src/main/kotlin/androidx/room/processor/TableEntityProcessor.kt
+++ b/room/compiler/src/main/kotlin/androidx/room/processor/TableEntityProcessor.kt
@@ -20,7 +20,6 @@
import androidx.room.parser.SqlParser
import androidx.room.compiler.processing.XType
import androidx.room.compiler.processing.XTypeElement
-import androidx.room.compiler.processing.requireEnclosingTypeElement
import androidx.room.ext.isNotNone
import androidx.room.processor.EntityProcessor.Companion.createIndexName
import androidx.room.processor.EntityProcessor.Companion.extractForeignKeys
@@ -110,7 +109,7 @@
Warning.INDEX_FROM_PARENT_FIELD_IS_DROPPED,
ProcessorErrors.droppedSuperClassFieldIndex(
it.columnName, element.qualifiedName,
- it.element.requireEnclosingTypeElement().qualifiedName
+ it.element.enclosingElement.className.toString()
)
)
null
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 3d5855b..9545f48 100644
--- a/room/compiler/src/main/kotlin/androidx/room/vo/Constructor.kt
+++ b/room/compiler/src/main/kotlin/androidx/room/vo/Constructor.kt
@@ -21,7 +21,6 @@
import androidx.room.compiler.processing.XExecutableElement
import androidx.room.compiler.processing.isConstructor
import androidx.room.compiler.processing.isMethod
-import androidx.room.compiler.processing.requireEnclosingTypeElement
import com.squareup.javapoet.CodeBlock
/**
@@ -54,7 +53,7 @@
// elements.
builder.addStatement(
"$L = $T.$L($L)", outVar,
- element.requireEnclosingTypeElement().className,
+ element.enclosingElement.className,
element.name, args
)
}