All Downloads are FREE. Search and download functionalities are using the official Maven repository.

name.remal.java.lang.Class.kt Maven / Gradle / Ivy

The newest version!
package name.remal

import name.remal.reflection.HierarchyUtils
import java.lang.reflect.Method
import java.lang.reflect.Modifier
import java.lang.reflect.Type

val Class<*>.resourceName get() = classNameToResourceName(name)

val Class<*>.isPublic get() = Modifier.isPublic(modifiers)
val Class<*>.isProtected get() = Modifier.isProtected(modifiers)
val Class<*>.isPackagePrivate get() = !Modifier.isPublic(modifiers) && !Modifier.isProtected(modifiers) && !Modifier.isPrivate(modifiers)
val Class<*>.isPrivate get() = Modifier.isPrivate(modifiers)
val Class<*>.isStatic get() = Modifier.isStatic(modifiers)
val Class<*>.isFinal get() = Modifier.isFinal(modifiers)
val Class<*>.isAbstract get() = Modifier.isAbstract(modifiers)
val Class<*>.isStrict get() = Modifier.isStrict(modifiers)

val Class<*>.hasSuperclass get() = superclass.let { it != null && this != it }

val Class<*>.packageName get() = name.substringBeforeLast('.', "")

val Class<*>.packageHierarchy: List get() = HierarchyUtils.getPackageHierarchy(this)
val  Class.superClassHierarchy: List> get() = HierarchyUtils.getSuperClassesHierarchy(this)
val  Class.hierarchy: List> get() = HierarchyUtils.getHierarchy(this)
val Class<*>.genericHierarchy: List get() = HierarchyUtils.getGenericHierarchy(this)

val Class<*>.allNotOverriddenMethods: List get() = HierarchyUtils.getAllNotOverriddenMethods(this)


fun Class<*>.unwrapPrimitive() = PrimitiveTypeUtils.unwrap(this)
fun Class<*>.wrapPrimitive() = PrimitiveTypeUtils.wrap(this)

fun Class<*>.compareByHierarchySize(other: Class<*>) = HierarchyUtils.compareByHierarchySize(this, other)

fun Class<*>.findField(name: String) = try {
    getField(name)
} catch (ignored: NoSuchFieldException) {
    null
}

fun Class<*>.findDeclaredField(name: String) = try {
    getDeclaredField(name)
} catch (ignored: NoSuchFieldException) {
    null
}

fun Class<*>.findConstructor(vararg parameterTypes: Class<*>) = try {
    getConstructor(*parameterTypes)
} catch (ignored: NoSuchMethodException) {
    null
}

fun Class<*>.findDeclaredConstructor(vararg parameterTypes: Class<*>) = try {
    getDeclaredConstructor(*parameterTypes)
} catch (ignored: NoSuchMethodException) {
    null
}

fun Class<*>.findMethod(name: String, vararg parameterTypes: Class<*>) = try {
    getMethod(name, *parameterTypes)
} catch (ignored: NoSuchMethodException) {
    null
}

fun Class<*>.findDeclaredMethod(name: String, vararg parameterTypes: Class<*>) = try {
    getDeclaredMethod(name, *parameterTypes)
} catch (ignored: NoSuchMethodException) {
    null
}


fun Class<*>.findCompatibleMethod(name: String, vararg paramTypes: Class<*>): Method? {
    if (paramTypes.isEmpty()) {
        return findMethod(name)
    }

    val candidateMethods = methods.filter { method -> method.name == name && method.parameterCount == paramTypes.size }
    return candidateMethods.firstOrNull { method -> paramTypes.allIndexed { index, paramType -> method.parameterTypes[index] == paramType } }
        ?: candidateMethods.firstOrNull { method -> paramTypes.allIndexed { index, paramType -> method.parameterTypes[index].isAssignableFrom(paramType) } }
}

fun Class<*>.findCompatibleMethod(returnType: Class<*>, name: String, vararg paramTypes: Class<*>): Method? {
    if (paramTypes.isEmpty()) {
        return findMethod(name).nullIf { !returnType.isAssignableFrom([email protected]) }
    }

    val candidateMethods = methods.filter { method -> method.name == name && method.parameterCount == paramTypes.size && returnType.isAssignableFrom(method.returnType) }
    return candidateMethods.firstOrNull { method -> paramTypes.allIndexed { index, paramType -> method.parameterTypes[index] == paramType } }
        ?: candidateMethods.firstOrNull { method -> paramTypes.allIndexed { index, paramType -> method.parameterTypes[index].isAssignableFrom(paramType) } }
}

private inline fun  Array.allIndexed(predicate: (index: Int, element: T) -> Boolean): Boolean {
    forEachIndexed { index, element ->
        if (!predicate(index, element)) {
            return false
        }
    }
    return true
}


fun Class<*>.getCompatibleMethod(name: String, vararg paramTypes: Class<*>): Method {
    val method = findCompatibleMethod(name, *paramTypes)
    if (method != null) {
        return method
    }
    throw CompatibleMethodNotFoundException(buildString {
        append("Compatible method not found: ")
        append([email protected])
        append('.')
        append(name)
        append('(')
        paramTypes.joinTo(this, ", ", transform = { it.name })
        append(')')
    })
}

fun Class<*>.getCompatibleMethod(returnType: Class<*>, name: String, vararg paramTypes: Class<*>): Method {
    val method = findCompatibleMethod(returnType, name, *paramTypes)
    if (method != null) {
        return method
    }
    throw CompatibleMethodNotFoundException(buildString {
        append("Compatible method not found: ")
        append(returnType.name)
        append(' ')
        append([email protected])
        append('.')
        append(name)
        append('(')
        paramTypes.joinTo(this, ", ", transform = { it.name })
        append(')')
    })
}

class CompatibleMethodNotFoundException : RuntimeException {
    constructor() : super()
    constructor(message: String?) : super(message)
    constructor(message: String?, cause: Throwable?) : super(message, cause)
    constructor(cause: Throwable?) : super(cause)
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy