diff --git a/CHANGELOG.md b/CHANGELOG.md index b9de6f605f1..b2ac8e30cf3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,31 @@ ## 0.23.0 +## 0.22.8 + +* `Common`: + * Add `List.breakAsPairs` extension + * Add `Sequence.padWith`/`Sequence.padStart`/`Sequence.padEnd` and `List.padWith`/`List.padStart`/`List.padEnd` extensions + +## 0.22.7 + +* `Versions`: + * `Kotlin`: `2.0.20` -> `2.0.21` + * `Compose`: `1.7.0-rc01` -> `1.7.0` +* `KSP`: + * `Sealed`: + * Change package of `GenerateSealedWorkaround`. Migration: replace `dev.inmo.microutils.kps.sealed.GenerateSealedWorkaround` -> `dev.inmo.micro_utils.ksp.sealed.GenerateSealedWorkaround` + +## 0.22.6 + +* `KSP`: + * `Generator`: + * Add extension `KSClassDeclaration.buildSubFileName` + * Add extension `KSClassDeclaration.companion` + * Add extension `KSClassDeclaration.resolveSubclasses` + * `Sealed`: + * Improvements + ## 0.22.5 * `Versions`: diff --git a/common/src/commonMain/kotlin/dev/inmo/micro_utils/common/BreakAsPairs.kt b/common/src/commonMain/kotlin/dev/inmo/micro_utils/common/BreakAsPairs.kt new file mode 100644 index 00000000000..d1e262e6188 --- /dev/null +++ b/common/src/commonMain/kotlin/dev/inmo/micro_utils/common/BreakAsPairs.kt @@ -0,0 +1,13 @@ +package dev.inmo.micro_utils.common + +fun List.breakAsPairs(): List> { + val result = mutableListOf>() + + for (i in 0 until size - 1) { + val first = get(i) + val second = get(i + 1) + result.add(first to second) + } + + return result +} diff --git a/common/src/commonMain/kotlin/dev/inmo/micro_utils/common/PadExtensions.kt b/common/src/commonMain/kotlin/dev/inmo/micro_utils/common/PadExtensions.kt new file mode 100644 index 00000000000..2bc5621d2ae --- /dev/null +++ b/common/src/commonMain/kotlin/dev/inmo/micro_utils/common/PadExtensions.kt @@ -0,0 +1,32 @@ +package dev.inmo.micro_utils.common + +inline fun Sequence.padWith(size: Int, inserter: (Sequence) -> Sequence): Sequence { + var result = this + while (result.count() < size) { + result = inserter(result) + } + return result +} + +inline fun Sequence.padEnd(size: Int, padBlock: (Int) -> T): Sequence = padWith(size) { it + padBlock(it.count()) } + +inline fun Sequence.padEnd(size: Int, o: T) = padEnd(size) { o } + +inline fun List.padWith(size: Int, inserter: (List) -> List): List { + var result = this + while (result.size < size) { + result = inserter(result) + } + return result +} +inline fun List.padEnd(size: Int, padBlock: (Int) -> T): List = asSequence().padEnd(size, padBlock).toList() + +inline fun List.padEnd(size: Int, o: T): List = asSequence().padEnd(size, o).toList() + +inline fun Sequence.padStart(size: Int, padBlock: (Int) -> T): Sequence = padWith(size) { sequenceOf(padBlock(it.count())) + it } + +inline fun Sequence.padStart(size: Int, o: T) = padStart(size) { o } + +inline fun List.padStart(size: Int, padBlock: (Int) -> T): List = asSequence().padStart(size, padBlock).toList() + +inline fun List.padStart(size: Int, o: T): List = asSequence().padStart(size, o).toList() diff --git a/gradle.properties b/gradle.properties index b6ef4debbfe..a0bc7c4fcb2 100644 --- a/gradle.properties +++ b/gradle.properties @@ -16,4 +16,4 @@ crypto_js_version=4.1.1 group=dev.inmo version=0.23.0 -android_code_version=273 +android_code_version=275 diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index e765e16b7b5..5cfbd9a49b9 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -6,7 +6,7 @@ kt-coroutines = "1.9.0" kslog = "1.3.6" -jb-compose = "1.7.0-rc01" +jb-compose = "1.7.0" jb-exposed = "0.55.0" jb-dokka = "1.9.20" diff --git a/ksp/generator/src/main/kotlin/KSClassDeclarationBuildSubFileName.kt b/ksp/generator/src/main/kotlin/KSClassDeclarationBuildSubFileName.kt new file mode 100644 index 00000000000..5f854a166f2 --- /dev/null +++ b/ksp/generator/src/main/kotlin/KSClassDeclarationBuildSubFileName.kt @@ -0,0 +1,13 @@ +package dev.inmo.micro_ksp.generator + +import com.google.devtools.ksp.symbol.KSClassDeclaration + +val KSClassDeclaration.buildSubFileName: String + get() { + val parentDeclarationCaptured = parentDeclaration + val simpleNameString = simpleName.asString() + return when (parentDeclarationCaptured) { + is KSClassDeclaration -> parentDeclarationCaptured.buildSubFileName + else -> "" + } + simpleNameString + } diff --git a/ksp/generator/src/main/kotlin/KSClassDeclarationCompanion.kt b/ksp/generator/src/main/kotlin/KSClassDeclarationCompanion.kt new file mode 100644 index 00000000000..2f7f859736d --- /dev/null +++ b/ksp/generator/src/main/kotlin/KSClassDeclarationCompanion.kt @@ -0,0 +1,8 @@ +package dev.inmo.micro_ksp.generator + +import com.google.devtools.ksp.symbol.KSClassDeclaration + +val KSClassDeclaration.companion + get() = declarations.firstNotNullOfOrNull { + (it as? KSClassDeclaration)?.takeIf { it.isCompanionObject } + } diff --git a/ksp/generator/src/main/kotlin/ResolveSubclasses.kt b/ksp/generator/src/main/kotlin/ResolveSubclasses.kt new file mode 100644 index 00000000000..ca6acc8c9b5 --- /dev/null +++ b/ksp/generator/src/main/kotlin/ResolveSubclasses.kt @@ -0,0 +1,11 @@ +package dev.inmo.micro_ksp.generator + +import com.google.devtools.ksp.symbol.KSClassDeclaration + +fun KSClassDeclaration.resolveSubclasses(): List { + return (getSealedSubclasses().flatMap { + it.resolveSubclasses() + }.ifEmpty { + sequenceOf(this) + }).toList() +} diff --git a/ksp/sealed/generator/src/main/kotlin/KSClassDeclarationGetGenerateSealedWorkaroundAnnotation.kt b/ksp/sealed/generator/src/main/kotlin/KSClassDeclarationGetGenerateSealedWorkaroundAnnotation.kt new file mode 100644 index 00000000000..aab653b1349 --- /dev/null +++ b/ksp/sealed/generator/src/main/kotlin/KSClassDeclarationGetGenerateSealedWorkaroundAnnotation.kt @@ -0,0 +1,11 @@ +package dev.inmo.micro_utils.ksp.sealed.generator + +import com.google.devtools.ksp.KspExperimental +import com.google.devtools.ksp.getAnnotationsByType +import com.google.devtools.ksp.symbol.KSClassDeclaration +import dev.inmo.micro_utils.ksp.sealed.GenerateSealedWorkaround +import dev.inmo.microutils.kps.sealed.GenerateSealedWorkaround as OldGenerateSealedWorkaround + +@OptIn(KspExperimental::class) +val KSClassDeclaration.getGenerateSealedWorkaroundAnnotation + get() = (getAnnotationsByType(GenerateSealedWorkaround::class).firstOrNull() ?: getAnnotationsByType(OldGenerateSealedWorkaround::class).firstOrNull()) diff --git a/ksp/sealed/generator/src/main/kotlin/Processor.kt b/ksp/sealed/generator/src/main/kotlin/Processor.kt index 6eca44452a7..d2c7e1f522e 100644 --- a/ksp/sealed/generator/src/main/kotlin/Processor.kt +++ b/ksp/sealed/generator/src/main/kotlin/Processor.kt @@ -15,9 +15,11 @@ import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy import com.squareup.kotlinpoet.PropertySpec import com.squareup.kotlinpoet.asTypeName import com.squareup.kotlinpoet.ksp.toClassName +import dev.inmo.micro_ksp.generator.buildSubFileName +import dev.inmo.micro_ksp.generator.companion import dev.inmo.micro_ksp.generator.findSubClasses import dev.inmo.micro_ksp.generator.writeFile -import dev.inmo.microutils.kps.sealed.GenerateSealedWorkaround +import dev.inmo.micro_utils.ksp.sealed.GenerateSealedWorkaround import java.io.File class Processor( @@ -51,10 +53,10 @@ class Processor( ksClassDeclaration: KSClassDeclaration, resolver: Resolver ) { - val annotation = ksClassDeclaration.getAnnotationsByType(GenerateSealedWorkaround::class).first() + val annotation = ksClassDeclaration.getGenerateSealedWorkaroundAnnotation val subClasses = ksClassDeclaration.resolveSubclasses( searchIn = resolver.getAllFiles(), - allowNonSealed = annotation.includeNonSealedSubTypes + allowNonSealed = annotation ?.includeNonSealedSubTypes ?: false ).distinct() val subClassesNames = subClasses.filter { when (it.classKind) { @@ -93,7 +95,10 @@ class Processor( ) addFunction( FunSpec.builder("values").apply { - receiver(ClassName(className.packageName, *className.simpleNames.toTypedArray(), "Companion")) + val companion = ksClassDeclaration.takeIf { it.isCompanionObject } ?.toClassName() + ?: ksClassDeclaration.companion ?.toClassName() + ?: ClassName(className.packageName, *className.simpleNames.toTypedArray(), "Companion") + receiver(companion) returns(setType) addCode( CodeBlock.of( @@ -107,7 +112,9 @@ class Processor( @OptIn(KspExperimental::class) override fun process(resolver: Resolver): List { (resolver.getSymbolsWithAnnotation(GenerateSealedWorkaround::class.qualifiedName!!)).filterIsInstance().forEach { - val prefix = it.getAnnotationsByType(GenerateSealedWorkaround::class).first().prefix + val prefix = (it.getGenerateSealedWorkaroundAnnotation) ?.prefix ?.takeIf { + it.isNotEmpty() + } ?: it.buildSubFileName.replaceFirst(it.simpleName.asString(), "") it.writeFile(prefix = prefix, suffix = "SealedWorkaround") { FileSpec.builder( it.packageName.asString(), diff --git a/ksp/sealed/generator/test/src/commonMain/kotlin/Test.kt b/ksp/sealed/generator/test/src/commonMain/kotlin/Test.kt index b88dc45e563..01c9e8e90b4 100644 --- a/ksp/sealed/generator/test/src/commonMain/kotlin/Test.kt +++ b/ksp/sealed/generator/test/src/commonMain/kotlin/Test.kt @@ -1,6 +1,6 @@ package dev.inmo.micro_utils.ksp.sealed.generator.test -import dev.inmo.microutils.kps.sealed.GenerateSealedWorkaround +import dev.inmo.micro_utils.ksp.sealed.GenerateSealedWorkaround @GenerateSealedWorkaround sealed interface Test { diff --git a/ksp/sealed/src/commonMain/kotlin/GenerateSealedWorkaround.kt b/ksp/sealed/src/commonMain/kotlin/GenerateSealedWorkaround.kt index c98eed90d8e..2146dff9346 100644 --- a/ksp/sealed/src/commonMain/kotlin/GenerateSealedWorkaround.kt +++ b/ksp/sealed/src/commonMain/kotlin/GenerateSealedWorkaround.kt @@ -1,4 +1,4 @@ -package dev.inmo.microutils.kps.sealed +package dev.inmo.micro_utils.ksp.sealed @Retention(AnnotationRetention.BINARY) @Target(AnnotationTarget.CLASS) diff --git a/ksp/sealed/src/commonMain/kotlin/OldGenerateSealedWorkaround.kt b/ksp/sealed/src/commonMain/kotlin/OldGenerateSealedWorkaround.kt new file mode 100644 index 00000000000..2a317c5a476 --- /dev/null +++ b/ksp/sealed/src/commonMain/kotlin/OldGenerateSealedWorkaround.kt @@ -0,0 +1,6 @@ +package dev.inmo.microutils.kps.sealed + +import dev.inmo.micro_utils.ksp.sealed.GenerateSealedWorkaround + +@Deprecated("Replaced", ReplaceWith("GenerateSealedWorkaround", "dev.inmo.micro_utils.ksp.sealed.GenerateSealedWorkaround")) +typealias GenerateSealedWorkaround = GenerateSealedWorkaround \ No newline at end of file