Advertisement
Guest User

Untitled

a guest
Feb 21st, 2019
58
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.42 KB | None | 0 0
  1. @AutoService(Processor::class)
  2. class AnalyticsEventProcessor : KotlinAbstractProcessor(), KotlinMetadataUtils {
  3. companion object {
  4. private val ANNOTATION = AnalyticsEvent::class.java
  5. }
  6.  
  7. ...
  8.  
  9. override fun process(
  10. annotations: Set<TypeElement>,
  11. roundEnv: RoundEnvironment
  12. ): Boolean {
  13.  
  14. // Get all elements that has been annotated with our annotation
  15. val annotatedElements = roundEnv.getElementsAnnotatedWith(ANNOTATION)
  16.  
  17. for (annotatedElement in annotatedElements) {
  18. // Check if the annotatedElement is a Kotlin sealed class
  19. val analyticsElement = getAnalyticsElement(annotatedElement) ?: continue
  20.  
  21. // Get all the declared inner class as our Analytics Event
  22. val declaredAnalyticsEvents = getDeclaredAnalyticsEvents(analyticsElement)
  23.  
  24. }
  25. return true
  26. }
  27.  
  28. private fun getAnalyticsElement(element: Element): TypeElement? {
  29. val kotlinMetadata = element.kotlinMetadata
  30. if (kotlinMetadata !is KotlinClassMetadata || element !is TypeElement) {
  31. // Not a Kotlin class
  32. messager.printMessage(
  33. Diagnostic.Kind.WARNING,
  34. "$element is not a Kotlin class."
  35. )
  36. return null
  37. }
  38. val proto = kotlinMetadata.data.classProto
  39. if (proto.modality != ProtoBuf.Modality.SEALED) {
  40. // Is not a sealed class
  41. messager.printMessage(
  42. Diagnostic.Kind.WARNING,
  43. "$element is not a sealed Kotlin class."
  44. )
  45. return null
  46. }
  47. return element
  48. }
  49.  
  50. private fun getDeclaredAnalyticsEvents(
  51. analyticsElement: TypeElement
  52. ): Map<ClassName, List<String>> {
  53. val analyticsEvents = mutableMapOf<ClassName, List<String>>()
  54. // Get all declared inner elements, but skip the last element
  55. // since the last element is the actual analyticsElement itself.
  56. val enclosedElements = analyticsElement.enclosedElements.dropLast(1)
  57.  
  58. val supertype = analyticsElement.asType()
  59.  
  60. for (element in enclosedElements) {
  61.  
  62. val type = element.asType()
  63. val kotlinMetadata = element.kotlinMetadata
  64.  
  65. if (kotlinMetadata !is KotlinClassMetadata || element !is TypeElement) {
  66. // Inner class is not a Kotlin class
  67. messager.printMessage(
  68. Diagnostic.Kind.WARNING,
  69. "$element is not a kotlin class."
  70. )
  71. continue
  72. } else if (!typeUtils.directSupertypes(type).contains(supertype)) {
  73. // Inner class does not extend from the enclosing sealed class
  74. messager.printMessage(
  75. Diagnostic.Kind.WARNING,
  76. "$element does not extend from $analyticsElement."
  77. )
  78. continue
  79. }
  80.  
  81. // Make use of KotlinPoet's ClassName to easily get the class' name.
  82. val eventClass = element.asClassName()
  83.  
  84. // Extract the primary constructor and its parameters as the event's parameters.
  85. val proto = kotlinMetadata.data.classProto
  86. val nameResolver = kotlinMetadata.data.nameResolver
  87.  
  88. if (proto.constructorCount == 0) {
  89. messager.printMessage(
  90. Diagnostic.Kind.WARNING,
  91. "$element has no constructor."
  92. )
  93. continue
  94. }
  95.  
  96. val mainConstructor = proto.constructorList[0]
  97. val eventParameters = mainConstructor.valueParameterList
  98. .map { valueParameter ->
  99. // Resolve the constructor parameter's name
  100. // using nameResolver.
  101. nameResolver.getString(valueParameter.name)
  102. }
  103.  
  104. analyticsEvents[eventClass] = eventParameters
  105. }
  106. return analyticsEvents
  107. }
  108. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement