-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
db34b25
commit f807f2b
Showing
11 changed files
with
263 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
plugins { | ||
id "org.jetbrains.kotlin.multiplatform" | ||
id "org.jetbrains.kotlin.plugin.serialization" | ||
id "com.android.library" | ||
} | ||
|
||
apply from: "$mppJvmJsAndroidLinuxMingwLinuxArm64Project" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
plugins { | ||
id "org.jetbrains.kotlin.jvm" | ||
} | ||
|
||
apply from: "$publish_jvm" | ||
|
||
repositories { | ||
mavenCentral() | ||
} | ||
|
||
dependencies { | ||
api project(":micro_utils.ksp.generator") | ||
api project(":micro_utils.ksp.variations") | ||
api libs.kotlin.poet | ||
api libs.ksp | ||
} | ||
|
||
java { | ||
sourceCompatibility = JavaVersion.VERSION_17 | ||
targetCompatibility = JavaVersion.VERSION_17 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
package dev.inmo.micro_utils.ksp.variations.generator | ||
|
||
import com.google.devtools.ksp.KspExperimental | ||
import com.google.devtools.ksp.getAnnotationsByType | ||
import com.google.devtools.ksp.processing.CodeGenerator | ||
import com.google.devtools.ksp.processing.Resolver | ||
import com.google.devtools.ksp.processing.SymbolProcessor | ||
import com.google.devtools.ksp.symbol.* | ||
import com.squareup.kotlinpoet.* | ||
import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy | ||
import com.squareup.kotlinpoet.ksp.toClassName | ||
import com.squareup.kotlinpoet.ksp.toKModifier | ||
import com.squareup.kotlinpoet.ksp.toTypeName | ||
import dev.inmo.micro_ksp.generator.companion | ||
import dev.inmo.micro_ksp.generator.findSubClasses | ||
import dev.inmo.micro_ksp.generator.writeFile | ||
import dev.inmo.micro_utils.ksp.variations.GenerateVariations | ||
import dev.inmo.micro_utils.ksp.variations.GenerationVariant | ||
|
||
class Processor( | ||
private val codeGenerator: CodeGenerator | ||
) : SymbolProcessor { | ||
private fun KSClassDeclaration.findSealedConnection(potentialSealedParent: KSClassDeclaration): Boolean { | ||
val targetClassname = potentialSealedParent.qualifiedName ?.asString() | ||
return superTypes.any { | ||
val itAsDeclaration = it.resolve().declaration as? KSClassDeclaration ?: return@any false | ||
targetClassname == (itAsDeclaration.qualifiedName ?.asString()) || (itAsDeclaration.getSealedSubclasses().any() && itAsDeclaration.findSealedConnection(potentialSealedParent)) | ||
} | ||
} | ||
|
||
private fun KSClassDeclaration.resolveSubclasses( | ||
searchIn: Sequence<KSAnnotated>, | ||
allowNonSealed: Boolean | ||
): Sequence<KSClassDeclaration> { | ||
return findSubClasses(searchIn).let { | ||
if (allowNonSealed) { | ||
it | ||
} else { | ||
it.filter { | ||
it.findSealedConnection(this) | ||
} | ||
} | ||
} | ||
} | ||
|
||
@OptIn(KspExperimental::class) | ||
private fun FileSpec.Builder.generateVariations( | ||
ksFunctionDeclaration: KSFunctionDeclaration, | ||
resolver: Resolver | ||
) { | ||
val annotation = ksFunctionDeclaration.getAnnotationsByType(GenerateVariations::class).first() | ||
val variations: List<Pair<List<GenerationVariant>, KSValueParameter>> = ksFunctionDeclaration.parameters.mapNotNull { | ||
val variationAnnotations = it.getAnnotationsByType(GenerationVariant::class).toList().ifEmpty { return@mapNotNull null } | ||
variationAnnotations to it | ||
} | ||
val accumulatedGenerations = mutableSetOf<FunSpec>() | ||
variations.forEach { (variations, parameter) -> | ||
if (accumulatedGenerations.isEmpty()) { | ||
variations.forEach { variation -> | ||
accumulatedGenerations.add( | ||
FunSpec.builder(ksFunctionDeclaration.simpleName.asString()).apply { | ||
modifiers.addAll(ksFunctionDeclaration.modifiers.mapNotNull { it.toKModifier() }) | ||
ksFunctionDeclaration.parameters.forEach { | ||
parameters.add( | ||
(if (it == parameter) { | ||
ParameterSpec | ||
.builder( | ||
variation.argName, | ||
if (variation.varargTypes.isEmpty()) { | ||
variation.type.asTypeName() | ||
} else { | ||
variation.type.parameterizedBy(*variation.varargTypes) | ||
} | ||
) | ||
.apply { | ||
val name = it.name ?.asString() ?: "this" | ||
if (it.isVararg) { | ||
defaultValue( | ||
""" | ||
*$name.map { it.${variation.conversion} }.toTypedArray() | ||
""".trimIndent() | ||
) | ||
} else { | ||
defaultValue("$name.${variation.conversion}") | ||
} | ||
} | ||
} 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() | ||
) | ||
} | ||
}.build() | ||
) | ||
} | ||
} else { | ||
|
||
} | ||
} | ||
accumulatedGenerations.forEach { | ||
addFunction(it) | ||
} | ||
} | ||
|
||
@OptIn(KspExperimental::class) | ||
override fun process(resolver: Resolver): List<KSAnnotated> { | ||
(resolver.getSymbolsWithAnnotation(GenerateVariations::class.qualifiedName!!)).filterIsInstance<KSFunctionDeclaration>().forEach { | ||
val prefix = (it.getAnnotationsByType(GenerateVariations::class)).firstOrNull() ?.prefix ?.takeIf { | ||
it.isNotEmpty() | ||
} ?: it.simpleName.asString().replaceFirst(it.simpleName.asString(), "") | ||
it.writeFile(prefix = prefix, suffix = "GeneratedVariation") { | ||
FileSpec.builder( | ||
it.packageName.asString(), | ||
"${it.simpleName.getShortName()}GeneratedVariation" | ||
).apply { | ||
addFileComment( | ||
""" | ||
THIS CODE HAVE BEEN GENERATED AUTOMATICALLY | ||
TO REGENERATE IT JUST DELETE FILE | ||
ORIGINAL FILE: ${it.containingFile ?.fileName} | ||
""".trimIndent() | ||
) | ||
generateVariations(it, resolver) | ||
}.build() | ||
} | ||
} | ||
|
||
return emptyList() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package dev.inmo.micro_utils.ksp.variations.generator | ||
|
||
import com.google.devtools.ksp.processing.SymbolProcessor | ||
import com.google.devtools.ksp.processing.SymbolProcessorEnvironment | ||
import com.google.devtools.ksp.processing.SymbolProcessorProvider | ||
|
||
class Provider : SymbolProcessorProvider { | ||
override fun create(environment: SymbolProcessorEnvironment): SymbolProcessor = Processor( | ||
environment.codeGenerator | ||
) | ||
} |
1 change: 1 addition & 0 deletions
1
...in/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
dev.inmo.micro_utils.ksp.variations.generator.Provider |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
plugins { | ||
id "org.jetbrains.kotlin.multiplatform" | ||
id "org.jetbrains.kotlin.plugin.serialization" | ||
id "com.android.library" | ||
id "com.google.devtools.ksp" | ||
} | ||
|
||
apply from: "$mppJvmJsAndroidLinuxMingwLinuxArm64Project" | ||
|
||
|
||
kotlin { | ||
sourceSets { | ||
commonMain { | ||
dependencies { | ||
api project(":micro_utils.ksp.variations") | ||
} | ||
} | ||
} | ||
} | ||
|
||
|
||
dependencies { | ||
add("kspCommonMainMetadata", project(":micro_utils.ksp.variations.generator")) | ||
} | ||
|
||
ksp { | ||
} |
16 changes: 16 additions & 0 deletions
16
ksp/variations/generator/test/src/commonMain/kotlin/SampleFun.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import dev.inmo.micro_utils.ksp.variations.GenerateVariations | ||
import dev.inmo.micro_utils.ksp.variations.GenerationVariant | ||
|
||
data class Sample( | ||
val value: String | ||
) | ||
|
||
@GenerateVariations | ||
fun sample( | ||
@GenerationVariant( | ||
"example", | ||
Sample::class, | ||
"value" | ||
) | ||
example: String = "12" | ||
) = println(example) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package dev.inmo.micro_utils.ksp.variations | ||
|
||
@Retention(AnnotationRetention.BINARY) | ||
@Target(AnnotationTarget.FUNCTION) | ||
annotation class GenerateVariations( | ||
val prefix: String = "" | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package dev.inmo.micro_utils.ksp.variations | ||
|
||
import kotlin.reflect.KClass | ||
|
||
@Retention(AnnotationRetention.BINARY) | ||
@Repeatable | ||
@Target(AnnotationTarget.TYPE_PARAMETER, AnnotationTarget.VALUE_PARAMETER) | ||
annotation class GenerationVariant( | ||
val argName: String, | ||
val type: KClass<*>, | ||
val conversion: String, | ||
vararg val varargTypes: KClass<*> | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters