name.remal.gradle_plugins.dsl.reflective_project_plugin.info.PluginInfoCollector.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of gradle-plugins-kotlin-dsl Show documentation
Show all versions of gradle-plugins-kotlin-dsl Show documentation
Remal Gradle plugins: gradle-plugins-kotlin-dsl
package name.remal.gradle_plugins.dsl.reflective_project_plugin.info
import name.remal.*
import name.remal.gradle_plugins.dsl.*
import name.remal.gradle_plugins.dsl.extensions.getOrInstantiate
import name.remal.gradle_plugins.dsl.utils.findPluginId
import name.remal.gradle_plugins.dsl.utils.getGradleLogger
import org.gradle.util.GradleVersion
import java.lang.reflect.AnnotatedElement
import java.lang.reflect.Method
import kotlin.reflect.full.memberProperties
object PluginInfoCollector {
private val logger = getGradleLogger(PluginInfoCollector::class.java)
@JvmStatic
fun collect(pluginClass: ProjectPluginClass): PluginInfo? {
val pluginAnnotation = pluginClass.getMetaAnnotation(Plugin::class.java) ?: return null
return PluginInfo(
pluginClass = pluginClass,
id = pluginAnnotation.id,
isHidden = pluginAnnotation.isHidden,
description = pluginAnnotation.description,
tags = pluginAnnotation.tags.toSet(),
conditionMethods = collectConditionMethods(pluginClass),
minGradleVersion = collectMinGradleVersion(pluginClass),
maxGradleVersion = collectMaxGradleVersion(pluginClass),
requirePluginIds = collectRequirePluginIds(pluginClass),
applyPluginIds = collectApplyPluginIds(pluginClass),
applyOptionalPluginIds = collectApplyOptionalPluginIds(pluginClass),
applyPluginClasses = collectApplyPluginClasses(pluginClass),
applyPluginIdsAtTheEnd = collectApplyPluginIdsAtTheEnd(pluginClass),
applyOptionalPluginIdsAtTheEnd = collectApplyOptionalPluginIdsAtTheEnd(pluginClass),
applyPluginClassesAtTheEnd = collectApplyPluginClassesAtTheEnd(pluginClass),
actionMethods = collectActions(pluginClass),
actionsGroups = collectActionsGroups(pluginClass)
);
}
private fun collectConditionMethods(pluginClass: Class<*>): List {
return buildList {
pluginClass.allNotOverriddenMethods.forEach { method ->
val conditionAnnotation = method.getMetaAnnotation(PluginCondition::class.java) ?: return@forEach
if (Boolean::class.javaPrimitiveType != method.returnType) return@forEach logger.warn("{} can't be plugin condition method - it doesn't return boolean")
add(ConditionMethodInfo(
method = method,
isHidden = conditionAnnotation.isHidden,
order = conditionAnnotation.order,
description = if (conditionAnnotation.value.isNotEmpty()) conditionAnnotation.value else method.name
))
}
}.sorted()
}
private fun collectMinGradleVersion(annotatedElement: AnnotatedElement): GradleVersion? {
return annotatedElement.getMetaAnnotation(MinGradleVersion::class.java)?.value?.native
}
private fun collectMaxGradleVersion(annotatedElement: AnnotatedElement): GradleVersion? {
return annotatedElement.getMetaAnnotation(MaxGradleVersion::class.java)?.value?.native
}
private fun collectRequirePluginIds(annotatedElement: AnnotatedElement): Set {
return buildSet {
annotatedElement.getMetaAnnotations(WithPlugins::class.java).forEach {
it.value.forEach { add(it.getOrInstantiate()) }
}
annotatedElement.getMetaAnnotations(WithPluginClasses::class.java).forEach {
it.value.forEach {
val id = findPluginId(it.java)
?: throw IllegalStateException("Plugin ID can't be find for %s".format(it.java))
add(PluginId(id))
}
}
}
}
private fun collectApplyPluginIds(annotatedElement: AnnotatedElement): Set {
return buildSet {
annotatedElement.getMetaAnnotations(ApplyPlugins::class.java).forEach {
it.value.forEach { add(it.getOrInstantiate()) }
}
}
}
private fun collectApplyOptionalPluginIds(annotatedElement: AnnotatedElement): Set {
return buildSet {
annotatedElement.getMetaAnnotations(ApplyOptionalPlugins::class.java).forEach {
it.value.forEach { add(it.getOrInstantiate()) }
}
}
}
private fun collectApplyPluginClasses(annotatedElement: AnnotatedElement): Set {
return buildSet {
annotatedElement.getMetaAnnotations(ApplyPluginClasses::class.java).forEach {
it.value.forEach { add(it.java) }
}
}
}
private fun collectApplyPluginIdsAtTheEnd(annotatedElement: AnnotatedElement): Set {
return buildSet {
annotatedElement.getMetaAnnotations(ApplyPluginsAtTheEnd::class.java).forEach {
it.value.forEach { add(it.getOrInstantiate()) }
}
}
}
private fun collectApplyOptionalPluginIdsAtTheEnd(annotatedElement: AnnotatedElement): Set {
return buildSet {
annotatedElement.getMetaAnnotations(ApplyOptionalPluginsAtTheEnd::class.java).forEach {
it.value.forEach { add(it.getOrInstantiate()) }
}
}
}
private fun collectApplyPluginClassesAtTheEnd(annotatedElement: AnnotatedElement): Set {
return buildSet {
annotatedElement.getMetaAnnotations(ApplyPluginClassesAtTheEnd::class.java).forEach {
it.value.forEach { add(it.java) }
}
}
}
private fun collectCreateExtensionInfo(method: Method): CreateExtensionInfo? {
val returnType = method.returnType
if (returnType.isPrimitive) return null
val extensionAnnotation = returnType.getMetaAnnotation(Extension::class.java) ?: return null
return CreateExtensionInfo(
extensionClass = returnType,
description = if (extensionAnnotation.value.isNotEmpty()) extensionAnnotation.value else returnType.simpleName,
properties = returnType.kotlin.memberProperties
.map {
val propertyAnnotation = it.getMetaAnnotation(ExtensionProperty::class.java) ?: return@map null
return@map ExtensionPropertyInfo(
name = it.name,
description = propertyAnnotation.value
)
}
.filterNotNull()
.sortedBy(ExtensionPropertyInfo::name)
)
}
private fun collectActions(contextClass: Class<*>): List {
return buildList {
contextClass.allNotOverriddenMethods.forEach { method ->
val actionAnnotation = method.getMetaAnnotation(PluginAction::class.java) ?: return@forEach
add(ActionMethodInfo(
method = method,
isHidden = actionAnnotation.isHidden,
order = actionAnnotation.order,
description = if (actionAnnotation.value.isNotEmpty()) actionAnnotation.value else method.name,
minGradleVersion = collectMinGradleVersion(method),
maxGradleVersion = collectMaxGradleVersion(method),
requirePluginIds = collectRequirePluginIds(method),
applyPluginIds = collectApplyPluginIds(method),
applyOptionalPluginIds = collectApplyOptionalPluginIds(method),
applyPluginClasses = collectApplyPluginClasses(method),
applyPluginIdsAtTheEnd = collectApplyPluginIdsAtTheEnd(method),
applyOptionalPluginIdsAtTheEnd = collectApplyOptionalPluginIdsAtTheEnd(method),
applyPluginClassesAtTheEnd = collectApplyPluginClassesAtTheEnd(method),
createExtensionInfo = collectCreateExtensionInfo(method),
isAfterProjectEvaluation = method.hasMetaAnnotation(AfterProjectEvaluation::class.java)
))
}
}.sorted()
}
private fun collectActionsGroups(contextClass: Class<*>): List {
return buildList {
contextClass.declaredClasses.forEach { innerClass ->
val groupAnnotation = innerClass.getMetaAnnotation(PluginActionsGroup::class.java) ?: return@forEach
add(ActionsGroupInfo(
actionsGroupClass = innerClass,
isHidden = groupAnnotation.isHidden,
order = groupAnnotation.order,
description = if (groupAnnotation.value.isNotEmpty()) groupAnnotation.value else innerClass.simpleName,
conditionMethods = collectConditionMethods(innerClass),
minGradleVersion = collectMinGradleVersion(innerClass),
maxGradleVersion = collectMaxGradleVersion(innerClass),
requirePluginIds = collectRequirePluginIds(innerClass),
applyPluginIds = collectApplyPluginIds(innerClass),
applyOptionalPluginIds = collectApplyOptionalPluginIds(innerClass),
applyPluginClasses = collectApplyPluginClasses(innerClass),
applyPluginIdsAtTheEnd = collectApplyPluginIdsAtTheEnd(innerClass),
applyOptionalPluginIdsAtTheEnd = collectApplyOptionalPluginIdsAtTheEnd(innerClass),
applyPluginClassesAtTheEnd = collectApplyPluginClassesAtTheEnd(innerClass),
actionMethods = collectActions(innerClass),
actionsGroups = collectActionsGroups(innerClass)
))
}
}.sorted()
}
}