name.remal.gradle_plugins.dsl.extensions.kotlin.Any.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.extensions
import groovy.lang.Closure
import name.remal.fromUpperCamelToLowerCamel
import name.remal.lambda.Function1
import name.remal.lambda.VoidFunction1
import name.remal.orNull
import name.remal.uncheckedCast
import org.gradle.api.Action
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.artifacts.repositories.ArtifactRepository
import org.gradle.api.artifacts.repositories.MavenArtifactRepository
import org.gradle.api.internal.HasConvention
import org.gradle.api.internal.IConventionAware
import org.gradle.api.plugins.Convention
import org.gradle.api.provider.Provider
import java.lang.reflect.Array
import java.util.*
import java.util.concurrent.Callable
import java.util.concurrent.CompletionStage
import java.util.concurrent.Future
import java.util.concurrent.atomic.AtomicBoolean
import java.util.concurrent.atomic.AtomicInteger
import java.util.concurrent.atomic.AtomicLong
import java.util.concurrent.atomic.AtomicReference
import java.util.function.*
import kotlin.DeprecationLevel.HIDDEN
import kotlin.reflect.KProperty1
import kotlin.reflect.jvm.javaMethod
import java.util.function.Function as JFunction
import kotlin.Function1 as KFunction1
import kotlin.reflect.KFunction1 as KReflectFunction1
val Any.convention: Convention
get() = when (this) {
is Project -> this.convention
is Task -> this.convention
else -> (this as HasConvention).convention
}
val Any.conventionOrNull: Convention?
get() = when (this) {
is Project -> this.convention
is Task -> this.convention
is HasConvention -> this.convention
else -> null
}
fun Any.addObjectMarker(markerType: Class): Boolean {
val convention = conventionOrNull ?: return false
if (markerType in convention) return false
val marker = markerType.getDeclaredConstructor()
.apply { isAccessible = true }
.newInstance()
convention.addPlugin(marker)
return true
}
fun Any.hasObjectMarker(markerType: Class) = markerType in conventionOrNull
interface ObjectMarker
data class ConventionWithSelf(val convention: Convention, val self: T)
val T.conventionWithSelf: ConventionWithSelf get() = ConventionWithSelf(this.convention, this)
fun T.defaultPropertyValue(property: KProperty1, func: (self: T) -> P) {
this as IConventionAware
conventionMapping.map(property.name) { func(this) }
}
fun T.defaultPropertyValue(property: KReflectFunction1, func: (self: T) -> P) {
val method = property.javaMethod ?: throw IllegalArgumentException("$property is not a method reference")
val name: String
if (method.name.length > 3 && method.name.startsWith("get") && method.name[3].isUpperCase()) {
name = method.name.substring(3).fromUpperCamelToLowerCamel()
} else if (method.name.length > 2 && method.name.startsWith("is") && method.name[2].isUpperCase()) {
name = method.name.substring(2).fromUpperCamelToLowerCamel()
} else {
throw IllegalArgumentException("Property name can't be retrieved for $property")
}
this as IConventionAware
conventionMapping.map(name) { func(this) }
}
@Suppress("ComplexMethod")
fun T.configureWith(configurer: Any?): T = apply {
if (configurer == null) {
// do nothing
} else if (configurer is Action<*>) {
configurer.uncheckedCast>().execute(this)
} else if (configurer is Closure<*>) {
configurer.toConfigureAction().execute(this)
} else if (configurer is Consumer<*>) {
configurer.uncheckedCast>().toConfigureAction().execute(this)
} else if (configurer is JFunction<*, *>) {
configurer.uncheckedCast>().toConfigureAction().execute(this)
} else if (configurer is KFunction1<*, *>) {
configurer.uncheckedCast>().toConfigureAction().execute(this)
} else if (configurer is KReflectFunction1<*, *>) {
configurer.uncheckedCast>().toConfigureAction().execute(this)
} else if (configurer is Function1<*, *>) {
configurer.uncheckedCast>().toConfigureAction().execute(this)
} else if (configurer is VoidFunction1<*>) {
configurer.uncheckedCast>().toConfigureAction().execute(this)
} else {
throw IllegalArgumentException("Unsupported configurer: ${configurer.javaClass.name}")
}
}
@Suppress("ComplexMethod")
fun Any?.unwrapProviders(): Any? = when (this) {
null -> null
is Optional<*> -> this.orNull.unwrapProviders()
is Provider<*> -> this.orNull.unwrapProviders()
is Callable<*> -> this.call().unwrapProviders()
is Supplier<*> -> this.get().unwrapProviders()
is BooleanSupplier -> this.asBoolean.unwrapProviders()
is IntSupplier -> this.asInt.unwrapProviders()
is LongSupplier -> this.asLong.unwrapProviders()
is DoubleSupplier -> this.asDouble.unwrapProviders()
is Future<*> -> this.get().unwrapProviders()
is CompletionStage<*> -> this.toCompletableFuture().get().unwrapProviders()
is AtomicBoolean -> this.get().unwrapProviders()
is AtomicInteger -> this.get().unwrapProviders()
is AtomicLong -> this.get().unwrapProviders()
is AtomicReference<*> -> this.get().unwrapProviders()
is Lazy<*> -> this.value.unwrapProviders()
is Closure<*> -> this.call().unwrapProviders()
else -> this
}
@Suppress("ReturnCount")
fun Any?.toStringSmart(): String {
if (this == null) return "null"
if (this.javaClass.isArray) {
return buildString {
append("[")
(0 until Array.getLength(this@toStringSmart)).joinTo(this, ", ", transform = { Array.get(this@toStringSmart, it).toStringSmart() })
append("]")
}
}
if (this is Iterable<*>) {
return buildString {
append("[")
[email protected](this, ", ", transform = { it.toStringSmart() })
append("]")
}
}
val toStringDeclaringClass = this.javaClass.getMethod("toString").declaringClass
if (Any::class.java == toStringDeclaringClass || toStringDeclaringClass.isInterface) {
when (this) {
is MavenArtifactRepository -> return "$name($url)"
is ArtifactRepository -> return name
}
}
return toString()
}
fun Any.invokeCompatibleMethod(name: String, vararg params: Any) {
val method = javaClass.getCompatibleMethod(name, *params.map(Any::javaClass).toTypedArray())
method.isAccessible = true
method.invoke(this, *params)
}
fun Any.invokeCompatibleMethod(returnType: Class, name: String, vararg params: Any): R {
val method = javaClass.getCompatibleMethod(returnType, name, *params.map(Any::javaClass).toTypedArray())
method.isAccessible = true
val result = method.invoke(this, *params)
?: throw IllegalStateException("$method returned NULL")
return result.uncheckedCast()
}
fun Any.invokeNullableCompatibleMethod(returnType: Class, name: String, vararg params: Any): R? {
val method = javaClass.getCompatibleMethod(returnType, name, *params.map(Any::javaClass).toTypedArray())
method.isAccessible = true
return method.invoke(this, *params)?.uncheckedCast()
}
@Deprecated("invokeCompatibleMethod() can't be called on Unit", level = HIDDEN)
@Suppress("unused", "UNUSED_PARAMETER")
fun Unit.invokeCompatibleMethod(name: String, vararg params: Any) {
throw UnsupportedOperationException()
}
@Deprecated("invokeCompatibleMethod() can't be called on Unit", level = HIDDEN)
@Suppress("unused", "UNUSED_PARAMETER")
fun Unit.invokeCompatibleMethod(returnType: Class, name: String, vararg params: Any): R {
throw UnsupportedOperationException()
}
@Deprecated("invokeNullableCompatibleMethod() can't be called on Unit", level = HIDDEN)
@Suppress("unused", "UNUSED_PARAMETER")
fun Unit.invokeNullableCompatibleMethod(returnType: Class, name: String, vararg params: Any): R? {
throw UnsupportedOperationException()
}