mirror of
https://github.com/InsanusMokrassar/MicroUtils.git
synced 2025-11-13 10:30:33 +00:00
fixes for generics
This commit is contained in:
25
ksp/generator/src/main/kotlin/KClassWorkarounds.kt
Normal file
25
ksp/generator/src/main/kotlin/KClassWorkarounds.kt
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
package dev.inmo.micro_ksp.generator
|
||||||
|
|
||||||
|
import com.google.devtools.ksp.KSTypeNotPresentException
|
||||||
|
import com.google.devtools.ksp.KSTypesNotPresentException
|
||||||
|
import com.google.devtools.ksp.KspExperimental
|
||||||
|
import com.google.devtools.ksp.symbol.KSType
|
||||||
|
import com.squareup.kotlinpoet.asClassName
|
||||||
|
import com.squareup.kotlinpoet.ksp.toClassName
|
||||||
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
|
@OptIn(KspExperimental::class)
|
||||||
|
inline fun convertToClassName(getter: () -> KClass<*>) = try {
|
||||||
|
getter().asClassName()
|
||||||
|
} catch (e: KSTypeNotPresentException) {
|
||||||
|
e.ksType.toClassName()
|
||||||
|
}
|
||||||
|
|
||||||
|
@OptIn(KspExperimental::class)
|
||||||
|
inline fun convertToClassNames(getter: () -> List<KClass<*>>) = try {
|
||||||
|
getter().map { it.asClassName() }
|
||||||
|
} catch (e: KSTypesNotPresentException) {
|
||||||
|
e.ksTypes.map {
|
||||||
|
it.toClassName()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,6 +9,7 @@ repositories {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
implementation libs.kt.stdlib
|
||||||
api project(":micro_utils.ksp.generator")
|
api project(":micro_utils.ksp.generator")
|
||||||
api project(":micro_utils.ksp.variations")
|
api project(":micro_utils.ksp.variations")
|
||||||
api libs.kotlin.poet
|
api libs.kotlin.poet
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package dev.inmo.micro_utils.ksp.variations.generator
|
package dev.inmo.micro_utils.ksp.variations.generator
|
||||||
|
|
||||||
|
import com.google.devtools.ksp.KSTypeNotPresentException
|
||||||
import com.google.devtools.ksp.KspExperimental
|
import com.google.devtools.ksp.KspExperimental
|
||||||
import com.google.devtools.ksp.getAnnotationsByType
|
import com.google.devtools.ksp.getAnnotationsByType
|
||||||
import com.google.devtools.ksp.processing.CodeGenerator
|
import com.google.devtools.ksp.processing.CodeGenerator
|
||||||
@@ -8,8 +9,11 @@ import com.google.devtools.ksp.processing.SymbolProcessor
|
|||||||
import com.google.devtools.ksp.symbol.*
|
import com.google.devtools.ksp.symbol.*
|
||||||
import com.squareup.kotlinpoet.*
|
import com.squareup.kotlinpoet.*
|
||||||
import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy
|
import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy
|
||||||
|
import com.squareup.kotlinpoet.ksp.toClassName
|
||||||
import com.squareup.kotlinpoet.ksp.toKModifier
|
import com.squareup.kotlinpoet.ksp.toKModifier
|
||||||
import com.squareup.kotlinpoet.ksp.toTypeName
|
import com.squareup.kotlinpoet.ksp.toTypeName
|
||||||
|
import dev.inmo.micro_ksp.generator.convertToClassName
|
||||||
|
import dev.inmo.micro_ksp.generator.convertToClassNames
|
||||||
import dev.inmo.micro_ksp.generator.findSubClasses
|
import dev.inmo.micro_ksp.generator.findSubClasses
|
||||||
import dev.inmo.micro_ksp.generator.writeFile
|
import dev.inmo.micro_ksp.generator.writeFile
|
||||||
import dev.inmo.micro_utils.ksp.variations.GenerateVariations
|
import dev.inmo.micro_utils.ksp.variations.GenerateVariations
|
||||||
@@ -128,27 +132,33 @@ class Processor(
|
|||||||
receiver(it)
|
receiver(it)
|
||||||
}
|
}
|
||||||
accumulatedGeneration.parameters.forEach {
|
accumulatedGeneration.parameters.forEach {
|
||||||
|
val actualName = if (variation.argName.isEmpty()) it.name else variation.argName
|
||||||
parameters.add(
|
parameters.add(
|
||||||
(if (it.name == (parameter.name ?.asString() ?: "this")) {
|
(if (it.name == (parameter.name ?.asString() ?: "this")) {
|
||||||
|
val type = convertToClassName { variation.type }
|
||||||
|
val genericTypes = convertToClassNames { variation.genericTypes.toList() }
|
||||||
ParameterSpec
|
ParameterSpec
|
||||||
.builder(
|
.builder(
|
||||||
variation.argName,
|
actualName,
|
||||||
if (variation.varargTypes.isEmpty()) {
|
if (genericTypes.isEmpty()) {
|
||||||
ClassName.bestGuess(variation.type)
|
type
|
||||||
} else {
|
} else {
|
||||||
ClassName.bestGuess(variation.type).parameterizedBy(
|
type.parameterizedBy(
|
||||||
*variation.varargTypes.map { it.asTypeName() }.toTypedArray()
|
*genericTypes.toTypedArray()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
.apply {
|
.apply {
|
||||||
val defaultValueString = if (it.modifiers.contains(KModifier.VARARG)) {
|
addModifiers(it.modifiers)
|
||||||
"""
|
val defaultValueString = """
|
||||||
*${variation.argName}.map { it.${variation.conversion} }.toTypedArray()
|
with(${actualName}) {${
|
||||||
""".trimIndent()
|
if (it.modifiers.contains(KModifier.VARARG)) {
|
||||||
} else {
|
"map { it.${variation.conversion} }.toTypedArray()"
|
||||||
"${variation.argName}.${variation.conversion}"
|
} else {
|
||||||
}
|
"${variation.conversion}"
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
""".trimIndent()
|
||||||
defaults[it.name] = defaultValueString
|
defaults[it.name] = defaultValueString
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -174,84 +184,6 @@ class Processor(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// if (accumulatedGenerations.isEmpty()) {
|
|
||||||
// variations.forEach { variation ->
|
|
||||||
// val defaults = mutableMapOf<String, String>()
|
|
||||||
// accumulatedGenerations.add(
|
|
||||||
// FunSpec.builder(ksFunctionDeclaration.simpleName.asString()).apply {
|
|
||||||
// modifiers.addAll(ksFunctionDeclaration.modifiers.mapNotNull { it.toKModifier() })
|
|
||||||
// ksFunctionDeclaration.extensionReceiver ?.let {
|
|
||||||
// receiver(it.toTypeName())
|
|
||||||
// }
|
|
||||||
// ksFunctionDeclaration.parameters.forEach {
|
|
||||||
// parameters.add(
|
|
||||||
// (if (it == parameter) {
|
|
||||||
// ParameterSpec
|
|
||||||
// .builder(
|
|
||||||
// variation.argName,
|
|
||||||
// if (variation.varargTypes.isEmpty()) {
|
|
||||||
// ClassName.bestGuess(variation.type)
|
|
||||||
// } else {
|
|
||||||
// ClassName.bestGuess(variation.type).parameterizedBy(
|
|
||||||
// *variation.varargTypes.map { it.asTypeName() }.toTypedArray()
|
|
||||||
// )
|
|
||||||
// }
|
|
||||||
// )
|
|
||||||
// } else {
|
|
||||||
// ParameterSpec
|
|
||||||
// .builder(
|
|
||||||
// it.name ?.asString() ?: return@forEach,
|
|
||||||
// it.type.toTypeName(),
|
|
||||||
// )
|
|
||||||
// })
|
|
||||||
// .apply {
|
|
||||||
// if (it.isCrossInline) {
|
|
||||||
// addModifiers(KModifier.CROSSINLINE)
|
|
||||||
// }
|
|
||||||
// if (it.isVal) {
|
|
||||||
// addModifiers(KModifier.VALUE)
|
|
||||||
// }
|
|
||||||
// if (it.isNoInline) {
|
|
||||||
// addModifiers(KModifier.NOINLINE)
|
|
||||||
// }
|
|
||||||
// if (it.isVararg) {
|
|
||||||
// addModifiers(KModifier.VARARG)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// .build()
|
|
||||||
// .apply {
|
|
||||||
// val name = it.name ?.asString() ?: "this"
|
|
||||||
// val defaultValueString = if (it.isVararg) {
|
|
||||||
// """
|
|
||||||
// *$name.map { it.${variation.conversion} }.toTypedArray()
|
|
||||||
// """.trimIndent()
|
|
||||||
// } else {
|
|
||||||
// "$name.${variation.conversion}"
|
|
||||||
// }
|
|
||||||
// defaults[this.name] = defaultValueString
|
|
||||||
// }
|
|
||||||
// )
|
|
||||||
// }
|
|
||||||
// val parameters = ksFunctionDeclaration.parameters.joinToString(", ") {
|
|
||||||
// val itName = it.name ?.asString() ?: "this"
|
|
||||||
// """
|
|
||||||
// $itName = ${defaults[itName] ?: itName}
|
|
||||||
// """.trimIndent()
|
|
||||||
// }
|
|
||||||
// addCode(
|
|
||||||
// """
|
|
||||||
// return ${ksFunctionDeclaration.simpleName.asString()}(
|
|
||||||
// $parameters
|
|
||||||
// )
|
|
||||||
// """.trimIndent()
|
|
||||||
// )
|
|
||||||
// }.build() to defaults.toMap()
|
|
||||||
// )
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// val reusingGenerations = accumulatedGenerations.toList()
|
|
||||||
// reusingGenerations
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
accumulatedGenerations.forEach {
|
accumulatedGenerations.forEach {
|
||||||
addFunction(it.first)
|
addFunction(it.first)
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ kotlin {
|
|||||||
sourceSets {
|
sourceSets {
|
||||||
commonMain {
|
commonMain {
|
||||||
dependencies {
|
dependencies {
|
||||||
|
implementation libs.kt.stdlib
|
||||||
api project(":micro_utils.ksp.variations")
|
api project(":micro_utils.ksp.variations")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,32 +1,51 @@
|
|||||||
|
package dev.inmo.micro_utils.ksp.variations.generator.test
|
||||||
|
|
||||||
import dev.inmo.micro_utils.ksp.variations.GenerateVariations
|
import dev.inmo.micro_utils.ksp.variations.GenerateVariations
|
||||||
import dev.inmo.micro_utils.ksp.variations.GenerationVariant
|
import dev.inmo.micro_utils.ksp.variations.GenerationVariant
|
||||||
|
|
||||||
data class Sample(
|
data class SimpleType(
|
||||||
val value: String
|
val value: String
|
||||||
)
|
)
|
||||||
|
|
||||||
|
data class GenericType<T>(
|
||||||
|
val value: T
|
||||||
|
)
|
||||||
|
|
||||||
@GenerateVariations
|
@GenerateVariations
|
||||||
fun sample(
|
fun sample(
|
||||||
@GenerationVariant(
|
@GenerationVariant(
|
||||||
"example",
|
SimpleType::class,
|
||||||
"Sample",
|
"value",
|
||||||
"value"
|
)
|
||||||
|
@GenerationVariant(
|
||||||
|
GenericType::class,
|
||||||
|
"value.toString()",
|
||||||
|
genericTypes = arrayOf(Int::class)
|
||||||
)
|
)
|
||||||
example: String = "12"
|
example: String = "12"
|
||||||
) = println(example)
|
) = println(example)
|
||||||
|
|
||||||
@GenerateVariations
|
@GenerateVariations
|
||||||
suspend fun Sample.sample2(
|
fun sampleVararg(
|
||||||
@GenerationVariant(
|
@GenerationVariant(
|
||||||
|
SimpleType::class,
|
||||||
|
"value",
|
||||||
|
)
|
||||||
|
vararg example: String = arrayOf("12")
|
||||||
|
) = println(example.joinToString())
|
||||||
|
|
||||||
|
@GenerateVariations
|
||||||
|
suspend fun SimpleType.sample2(
|
||||||
|
@GenerationVariant(
|
||||||
|
Int::class,
|
||||||
|
"toString()",
|
||||||
"arg12",
|
"arg12",
|
||||||
"kotlin.Int",
|
|
||||||
"toString()"
|
|
||||||
)
|
)
|
||||||
arg1: String = "1",
|
arg1: String = "1",
|
||||||
@GenerationVariant(
|
@GenerationVariant(
|
||||||
|
String::class,
|
||||||
|
"toInt()",
|
||||||
"arg22",
|
"arg22",
|
||||||
"kotlin.String",
|
|
||||||
"toInt()"
|
|
||||||
)
|
)
|
||||||
arg2: Int = 2,
|
arg2: Int = 2,
|
||||||
arg3: Boolean = false
|
arg3: Boolean = false
|
||||||
|
|||||||
@@ -1,47 +1,49 @@
|
|||||||
// THIS CODE HAVE BEEN GENERATED AUTOMATICALLY
|
// THIS CODE HAVE BEEN GENERATED AUTOMATICALLY
|
||||||
// TO REGENERATE IT JUST DELETE FILE
|
// TO REGENERATE IT JUST DELETE FILE
|
||||||
// ORIGINAL FILE: SampleFun.kt
|
// ORIGINAL FILE: SampleFun.kt
|
||||||
|
package dev.inmo.micro_utils.ksp.variations.generator.test
|
||||||
|
|
||||||
import kotlin.Boolean
|
import kotlin.Boolean
|
||||||
import kotlin.Int
|
import kotlin.Int
|
||||||
import kotlin.String
|
import kotlin.String
|
||||||
import kotlin.Unit
|
import kotlin.Unit
|
||||||
|
|
||||||
public suspend fun Sample.sample2(arg12: Int): Unit = sample2(
|
public suspend fun SimpleType.sample2(arg12: Int): Unit = sample2(
|
||||||
arg1 = arg12.toString()
|
arg1 = with(arg12) {toString()}
|
||||||
)
|
)
|
||||||
|
|
||||||
public suspend fun Sample.sample2(arg12: Int, arg2: Int): Unit = sample2(
|
public suspend fun SimpleType.sample2(arg12: Int, arg2: Int): Unit = sample2(
|
||||||
arg1 = arg12.toString(), arg2 = arg2
|
arg1 = with(arg12) {toString()}, arg2 = arg2
|
||||||
)
|
)
|
||||||
|
|
||||||
public suspend fun Sample.sample2(arg12: Int, arg3: Boolean): Unit = sample2(
|
public suspend fun SimpleType.sample2(arg12: Int, arg3: Boolean): Unit = sample2(
|
||||||
arg1 = arg12.toString(), arg3 = arg3
|
arg1 = with(arg12) {toString()}, arg3 = arg3
|
||||||
)
|
)
|
||||||
|
|
||||||
public suspend fun Sample.sample2(
|
public suspend fun SimpleType.sample2(
|
||||||
arg12: Int,
|
arg12: Int,
|
||||||
arg2: Int,
|
arg2: Int,
|
||||||
arg3: Boolean,
|
arg3: Boolean,
|
||||||
): Unit = sample2(
|
): Unit = sample2(
|
||||||
arg1 = arg12.toString(), arg2 = arg2, arg3 = arg3
|
arg1 = with(arg12) {toString()}, arg2 = arg2, arg3 = arg3
|
||||||
)
|
)
|
||||||
|
|
||||||
public suspend fun Sample.sample2(arg22: String): Unit = sample2(
|
public suspend fun SimpleType.sample2(arg22: String): Unit = sample2(
|
||||||
arg2 = arg22.toInt()
|
arg2 = with(arg22) {toInt()}
|
||||||
)
|
)
|
||||||
|
|
||||||
public suspend fun Sample.sample2(arg1: String, arg22: String): Unit = sample2(
|
public suspend fun SimpleType.sample2(arg1: String, arg22: String): Unit = sample2(
|
||||||
arg1 = arg1, arg2 = arg22.toInt()
|
arg1 = arg1, arg2 = with(arg22) {toInt()}
|
||||||
)
|
)
|
||||||
|
|
||||||
public suspend fun Sample.sample2(arg22: String, arg3: Boolean): Unit = sample2(
|
public suspend fun SimpleType.sample2(arg22: String, arg3: Boolean): Unit = sample2(
|
||||||
arg2 = arg22.toInt(), arg3 = arg3
|
arg2 = with(arg22) {toInt()}, arg3 = arg3
|
||||||
)
|
)
|
||||||
|
|
||||||
public suspend fun Sample.sample2(
|
public suspend fun SimpleType.sample2(
|
||||||
arg1: String,
|
arg1: String,
|
||||||
arg22: String,
|
arg22: String,
|
||||||
arg3: Boolean,
|
arg3: Boolean,
|
||||||
): Unit = sample2(
|
): Unit = sample2(
|
||||||
arg1 = arg1, arg2 = arg22.toInt(), arg3 = arg3
|
arg1 = arg1, arg2 = with(arg22) {toInt()}, arg3 = arg3
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,8 +1,15 @@
|
|||||||
// THIS CODE HAVE BEEN GENERATED AUTOMATICALLY
|
// THIS CODE HAVE BEEN GENERATED AUTOMATICALLY
|
||||||
// TO REGENERATE IT JUST DELETE FILE
|
// TO REGENERATE IT JUST DELETE FILE
|
||||||
// ORIGINAL FILE: SampleFun.kt
|
// ORIGINAL FILE: SampleFun.kt
|
||||||
|
package dev.inmo.micro_utils.ksp.variations.generator.test
|
||||||
|
|
||||||
|
import kotlin.Int
|
||||||
import kotlin.Unit
|
import kotlin.Unit
|
||||||
|
|
||||||
public fun sample(example: Sample): Unit = sample(
|
public fun sample(example: SimpleType): Unit = sample(
|
||||||
example = example.value
|
example = with(example) {value}
|
||||||
|
)
|
||||||
|
|
||||||
|
public fun sample(example: GenericType<Int>): Unit = sample(
|
||||||
|
example = with(example) {value.toString()}
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
// THIS CODE HAVE BEEN GENERATED AUTOMATICALLY
|
||||||
|
// TO REGENERATE IT JUST DELETE FILE
|
||||||
|
// ORIGINAL FILE: SampleFun.kt
|
||||||
|
package dev.inmo.micro_utils.ksp.variations.generator.test
|
||||||
|
|
||||||
|
import kotlin.Unit
|
||||||
|
|
||||||
|
public fun sampleVararg(vararg example: SimpleType): Unit = sampleVararg(
|
||||||
|
example = with(example) {map { it.value }.toTypedArray()}
|
||||||
|
)
|
||||||
@@ -2,12 +2,17 @@ package dev.inmo.micro_utils.ksp.variations
|
|||||||
|
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param argName New argument name. Default - empty - means "use default arg name"
|
||||||
|
* @param type Qualified class name, like "dev.inmo.micro_utils.ksp.variants.GenerationVariant"
|
||||||
|
* @param conversion Conversion string with `this`
|
||||||
|
*/
|
||||||
@Retention(AnnotationRetention.BINARY)
|
@Retention(AnnotationRetention.BINARY)
|
||||||
@Repeatable
|
@Repeatable
|
||||||
@Target(AnnotationTarget.TYPE_PARAMETER, AnnotationTarget.VALUE_PARAMETER)
|
@Target(AnnotationTarget.TYPE_PARAMETER, AnnotationTarget.VALUE_PARAMETER)
|
||||||
annotation class GenerationVariant(
|
annotation class GenerationVariant(
|
||||||
val argName: String,
|
val type: KClass<*>,
|
||||||
val type: String,
|
|
||||||
val conversion: String,
|
val conversion: String,
|
||||||
vararg val varargTypes: KClass<*>
|
val argName: String = "",
|
||||||
|
vararg val genericTypes: KClass<*>
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user