gsonpath.adapter.util.AdapterFactoryUtil.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of gsonpath-compiler Show documentation
Show all versions of gsonpath-compiler Show documentation
An annotation processor which generates Type Adapters for the Google Gson library
The newest version!
package gsonpath.adapter.util
import com.squareup.javapoet.ClassName
import gsonpath.ProcessingException
import javax.annotation.processing.RoundEnvironment
import javax.lang.model.element.Element
import javax.lang.model.element.ElementKind
import javax.lang.model.element.TypeElement
object AdapterFactoryUtil {
inline fun getAnnotatedModelElements(
env: RoundEnvironment,
annotations: Set,
supportedElementKinds: List = listOf(ElementKind.CLASS)): Set> {
val supportedAnnotations = getSupportedAnnotations(annotations, T::class.java)
val customAnnotations = getCustomAnnotations(annotations, T::class.java)
// Avoid going any further if no supported annotations are found.
if (supportedAnnotations.isEmpty() && customAnnotations.isEmpty()) {
return emptySet()
}
return addModelElements(env, customAnnotations, supportedElementKinds)
.plus(addCustomModelElements(env, customAnnotations, supportedElementKinds))
.toSet()
}
inline fun addModelElements(
environment: RoundEnvironment,
customAnnotations: List,
supportedElementKinds: List
): Sequence> {
return environment
.getElementsAnnotatedWith(T::class.java)
.asSequence()
.filter {
filterElementKind(
element = it,
supportedElementKinds = supportedElementKinds,
allowCustomAnnotation = true,
annotationReference = T::class.java)
}
.map {
ElementAndAnnotation(it as TypeElement, it.getAnnotation(T::class.java))
}
.filter {
!customAnnotations.contains(it.element)
}
}
inline fun addCustomModelElements(
environment: RoundEnvironment,
customAnnotations: List,
supportedElementKinds: List
): List> {
return customAnnotations.flatMap { customAnnotation ->
environment
.getElementsAnnotatedWith(customAnnotation)
.filter {
filterElementKind(
element = it,
supportedElementKinds = supportedElementKinds,
allowCustomAnnotation = false,
annotationReference = customAnnotation)
}
.map {
ElementAndAnnotation(it as TypeElement, customAnnotation.getAnnotation(T::class.java))
}
}
}
fun filterElementKind(
element: Element,
supportedElementKinds: List,
allowCustomAnnotation: Boolean,
annotationReference: Any
): Boolean {
if (allowCustomAnnotation && element.kind == ElementKind.ANNOTATION_TYPE) {
return false
}
if (!supportedElementKinds.contains(element.kind)) {
throw ProcessingException("$annotationReference can only be used with types: [${supportedElementKinds.joinToString()}]", element)
}
return true
}
fun getSupportedAnnotations(annotations: Set, annotationClassName: Class) =
annotations
.asSequence()
.map(ClassName::get)
.filter { it == ClassName.get(annotationClassName) }
.toList()
fun getCustomAnnotations(annotations: Set, annotationClassName: Class) =
annotations.filter { it.getAnnotation(annotationClassName) != null }
}
data class ElementAndAnnotation(
val element: TypeElement,
val annotation: T
)