Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- @AutoService(Processor::class)
- class AnalyticsEventProcessor : KotlinAbstractProcessor(), KotlinMetadataUtils {
- companion object {
- private val ANNOTATION = AnalyticsEvent::class.java
- }
- ...
- override fun process(
- annotations: Set<TypeElement>,
- roundEnv: RoundEnvironment
- ): Boolean {
- // Get all elements that has been annotated with our annotation
- val annotatedElements = roundEnv.getElementsAnnotatedWith(ANNOTATION)
- for (annotatedElement in annotatedElements) {
- // Check if the annotatedElement is a Kotlin sealed class
- val analyticsElement = getAnalyticsElement(annotatedElement) ?: continue
- // Get all the declared inner class as our Analytics Event
- val declaredAnalyticsEvents = getDeclaredAnalyticsEvents(analyticsElement)
- }
- return true
- }
- private fun getAnalyticsElement(element: Element): TypeElement? {
- val kotlinMetadata = element.kotlinMetadata
- if (kotlinMetadata !is KotlinClassMetadata || element !is TypeElement) {
- // Not a Kotlin class
- messager.printMessage(
- Diagnostic.Kind.WARNING,
- "$element is not a Kotlin class."
- )
- return null
- }
- val proto = kotlinMetadata.data.classProto
- if (proto.modality != ProtoBuf.Modality.SEALED) {
- // Is not a sealed class
- messager.printMessage(
- Diagnostic.Kind.WARNING,
- "$element is not a sealed Kotlin class."
- )
- return null
- }
- return element
- }
- private fun getDeclaredAnalyticsEvents(
- analyticsElement: TypeElement
- ): Map<ClassName, List<String>> {
- val analyticsEvents = mutableMapOf<ClassName, List<String>>()
- // Get all declared inner elements, but skip the last element
- // since the last element is the actual analyticsElement itself.
- val enclosedElements = analyticsElement.enclosedElements.dropLast(1)
- val supertype = analyticsElement.asType()
- for (element in enclosedElements) {
- val type = element.asType()
- val kotlinMetadata = element.kotlinMetadata
- if (kotlinMetadata !is KotlinClassMetadata || element !is TypeElement) {
- // Inner class is not a Kotlin class
- messager.printMessage(
- Diagnostic.Kind.WARNING,
- "$element is not a kotlin class."
- )
- continue
- } else if (!typeUtils.directSupertypes(type).contains(supertype)) {
- // Inner class does not extend from the enclosing sealed class
- messager.printMessage(
- Diagnostic.Kind.WARNING,
- "$element does not extend from $analyticsElement."
- )
- continue
- }
- // Make use of KotlinPoet's ClassName to easily get the class' name.
- val eventClass = element.asClassName()
- // Extract the primary constructor and its parameters as the event's parameters.
- val proto = kotlinMetadata.data.classProto
- val nameResolver = kotlinMetadata.data.nameResolver
- if (proto.constructorCount == 0) {
- messager.printMessage(
- Diagnostic.Kind.WARNING,
- "$element has no constructor."
- )
- continue
- }
- val mainConstructor = proto.constructorList[0]
- val eventParameters = mainConstructor.valueParameterList
- .map { valueParameter ->
- // Resolve the constructor parameter's name
- // using nameResolver.
- nameResolver.getString(valueParameter.name)
- }
- analyticsEvents[eventClass] = eventParameters
- }
- return analyticsEvents
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement