83 lines
2.6 KiB
Kotlin
83 lines
2.6 KiB
Kotlin
package nl.voidcorp.depinj
|
|
|
|
import java.io.File
|
|
import java.io.IOException
|
|
import kotlin.reflect.KClass
|
|
import kotlin.reflect.KProperty
|
|
import kotlin.reflect.full.isSuperclassOf
|
|
import kotlin.reflect.jvm.jvmName
|
|
|
|
private val classes = mutableListOf<KClass<out Any>>()
|
|
val classesP: List<KClass<out Any>>
|
|
get() {
|
|
if (classes.isEmpty()) init()
|
|
return classes
|
|
}
|
|
|
|
class Dep<T>(val block: (property: KProperty<*>) -> T) {
|
|
operator fun getValue(thisRef: Any?, property: KProperty<*>) = block(property)
|
|
}
|
|
|
|
inline fun <reified T : Any> single(): Dep<T> {
|
|
return Dep {
|
|
classesP
|
|
.first { T::class.isSuperclassOf(it) && !it.java.isInterface }
|
|
.constructors.first { it.parameters.isEmpty() }.call() as T
|
|
}
|
|
|
|
}
|
|
|
|
inline fun <reified T : Any> multi(): Dep<List<T>> {
|
|
return Dep {
|
|
classesP
|
|
.filter { T::class.isSuperclassOf(it) && !it.java.isInterface }
|
|
.map { cls -> cls.constructors.first { it.parameters.isEmpty() }.call() as T }
|
|
}
|
|
}
|
|
|
|
private fun init() {
|
|
classes.addAll(Package.getPackages().map { getClasses(it.name) }.flatten())
|
|
}
|
|
|
|
@Throws(ClassNotFoundException::class, IOException::class)
|
|
private fun getClasses(packageName: String): List<KClass<out Any>> {
|
|
val classLoader = Thread.currentThread().contextClassLoader!!
|
|
val path = packageName.replace('.', '/')
|
|
val resources = classLoader.getResources(path)
|
|
val dirs = mutableListOf<File>()
|
|
|
|
while (resources.hasMoreElements()) {
|
|
val resource = resources.nextElement()
|
|
dirs.add(File(resource.file))
|
|
}
|
|
|
|
val classes = mutableListOf<Class<*>>()
|
|
for (directory in dirs) {
|
|
classes.addAll(findClasses(directory, packageName))
|
|
|
|
}
|
|
return classes.map { it.kotlin }.filterNot { it.java.isSynthetic }
|
|
.filterNot { Class.forName("kotlin.jvm.internal.Lambda").isAssignableFrom(it.java) }
|
|
.filterNot { it.jvmName.endsWith("Kt") }
|
|
.filterNot { it.jvmName.contains("$1") }
|
|
|
|
}
|
|
|
|
@Throws(ClassNotFoundException::class)
|
|
private fun findClasses(directory: File, packageName: String): List<Class<*>> {
|
|
val classes = mutableListOf<Class<*>>()
|
|
if (!directory.exists()) {
|
|
return classes
|
|
}
|
|
val files = directory.listFiles()
|
|
for (file in files!!) {
|
|
if (file.isDirectory) {
|
|
assert(!file.name.contains("."))
|
|
classes.addAll(findClasses(file, packageName + "." + file.name))
|
|
} else if (file.name.endsWith(".class")) {
|
|
classes.add(Class.forName(packageName + '.'.toString() + file.name.substring(0, file.name.length - 6)))
|
|
}
|
|
}
|
|
return classes
|
|
|
|
} |