For <Showkase> we generate kotlin code that can ca...
# androidx-xprocessing
e
For Showkase we generate kotlin code that can call Composable functions. With XProcessing though afaict there isn’t a way to tell whether a function is top level or not. The
XMemberContainer
lets top level functions be represented and access the JVM name, which is fine for Java codegen, but it would be nice to have a direct way to tell this info for kotlin codegen. Right now I’m using reflection to get the kotlin metadata in the kapt case, and using the assumption that the
XMemberContainer
is not an XTypeElement in the KSP caes
y
You can check if the container has a type or not
e
oh that would be nice if it works, the documentation is a little confusing though -
The [XType] for the container if this is an [XTypeElement]
, but according to the
enclosingElement
kdoc the member container is an XTypeElement in certain cases. Is the type null even in those cases?
I just ran a test, the type is non null in kapt. This test currently fails
Copy code
@Test
    fun isTopLevelFunction() {
        val libSource = Source.kotlin(
            "lib.kt",
            """
            @com.airbnb.android.showkase.processor.models.MyAnnotation
            fun foo() {}
            
            class Bar {
                fun enclosedFoo() {}
            }
            """.trimIndent()
        )
        runProcessorTest(listOf(libSource)) { invocation ->
            val barClass = invocation.processingEnv.requireTypeElement("Bar")

            expectThat(barClass.getDeclaredMethods()
                .single())
                .get { enclosingElement.type }
                .isNotNull()

            expectThat(invocation.roundEnv.getElementsAnnotatedWith(MyAnnotation::class))
                .single()
                .isA<XMethodElement>()
                 // This fails
                .get { enclosingElement.type }
                .isNull()
        }
    }
d
XMemberContainer.type
is not a good check due to the KAPT / KSP inconsistency. For KAPT there is always a container and
type
will not be null. And in KSP only if the top-level function is in source, it won’t have a
type
but if its from compiled code it will.
I think the documentation is relevant in the context of what
XMemberContainer
is which is explained here https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:room/roo[…]droidx/room/compiler/processing/XExecutableElement.kt;l=28-35
But I have a feeling we don’t have a good API to check if a function is top level in xprocessing…
e
yes, the documentation seems good, it just unfortunately means there are quite a few different cases, and in the case of an XTypeElement implementation of the container it is indistinguishable from a nested function. anyway, just wanted to raise this limitation. my reflection based approach seems to be working for now, but it would be nice to have an official API added for this