From 877b62fe5de79acfc22f0bf8e2d3a48e3b4636da Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Wed, 24 Jul 2024 00:06:18 +0600 Subject: [PATCH 1/5] start 0.21.5 --- CHANGELOG.md | 2 ++ gradle.properties | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ba66f838458..3d419a93774 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ # Changelog +## 0.21.5 + ## 0.21.4 * `Common`: diff --git a/gradle.properties b/gradle.properties index 780ec2fb0fb..92bac1cd669 100644 --- a/gradle.properties +++ b/gradle.properties @@ -15,5 +15,5 @@ crypto_js_version=4.1.1 # Project data group=dev.inmo -version=0.21.4 -android_code_version=263 +version=0.21.5 +android_code_version=264 From 52157ee0e7f3d4dca66a32a71c3d597dac5c881a Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Wed, 24 Jul 2024 00:34:49 +0600 Subject: [PATCH 2/5] start moving to kotlinx-io --- common/build.gradle | 1 + .../dev/inmo/micro_utils/common/MPPFile.kt | 35 ++++++++++++++++--- gradle/libs.versions.toml | 3 ++ 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/common/build.gradle b/common/build.gradle index 01489bbf4f1..d4fc46ec83d 100644 --- a/common/build.gradle +++ b/common/build.gradle @@ -11,6 +11,7 @@ kotlin { commonMain { dependencies { api libs.klock + api libs.kt.io } } jvmMain { diff --git a/common/src/commonMain/kotlin/dev/inmo/micro_utils/common/MPPFile.kt b/common/src/commonMain/kotlin/dev/inmo/micro_utils/common/MPPFile.kt index 7aef8ed8c9a..fd397e0d811 100644 --- a/common/src/commonMain/kotlin/dev/inmo/micro_utils/common/MPPFile.kt +++ b/common/src/commonMain/kotlin/dev/inmo/micro_utils/common/MPPFile.kt @@ -1,5 +1,11 @@ package dev.inmo.micro_utils.common +import kotlinx.io.Buffer +import kotlinx.io.Source +import kotlinx.io.buffered +import kotlinx.io.files.Path +import kotlinx.io.files.SystemFileSystem +import kotlinx.io.readByteArray import kotlinx.serialization.Serializable import kotlin.jvm.JvmInline @@ -23,12 +29,31 @@ value class FileName(val string: String) { } -expect class MPPFile +typealias MPPFile = Path -expect val MPPFile.filename: FileName -expect val MPPFile.filesize: Long -expect val MPPFile.bytesAllocatorSync: ByteArrayAllocator -expect val MPPFile.bytesAllocator: SuspendByteArrayAllocator +val MPPFile.filename: FileName + get() = FileName(name) +val MPPFile.filesize: Long + get() = SystemFileSystem.metadataOrNull(this) ?.size ?.takeIf { it > -1 } ?: error("Path $filename does not exists or is folder") +val MPPFile.bytesAllocatorSync: ByteArrayAllocator + get() = { + source().readByteArray() + } +val MPPFile.bytesAllocator: SuspendByteArrayAllocator + get() = { + bytesAllocatorSync() + } fun MPPFile.bytesSync() = bytesAllocatorSync() suspend fun MPPFile.bytes() = bytesAllocator() +fun MPPFile.source(): Source = SystemFileSystem.source(this).buffered() + + +//expect class MPPFile +// +//expect val MPPFile.filename: FileName +//expect val MPPFile.filesize: Long +//expect val MPPFile.bytesAllocatorSync: ByteArrayAllocator +//expect val MPPFile.bytesAllocator: SuspendByteArrayAllocator +//fun MPPFile.bytesSync() = bytesAllocatorSync() +//suspend fun MPPFile.bytes() = bytesAllocator() diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 84313b0b175..e68dec8a2d6 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -4,6 +4,8 @@ kt = "1.9.23" kt-serialization = "1.6.3" kt-coroutines = "1.8.1" +kt-io = "0.5.1" + kslog = "1.3.4" jb-compose = "1.6.2" @@ -53,6 +55,7 @@ kt-coroutines = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", vers kt-coroutines-android = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android", version.ref = "kt-coroutines" } kt-coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "kt-coroutines" } +kt-io = { module = "org.jetbrains.kotlinx:kotlinx-io-core", version.ref = "kt-io" } ktor-io = { module = "io.ktor:ktor-io", version.ref = "ktor" } ktor-serialization-kotlinx-json = { module = "io.ktor:ktor-serialization-kotlinx-json", version.ref = "ktor" } From d164813bb4b8f1a7db8dbad1cd1f23dc7afabc62 Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Thu, 25 Jul 2024 01:20:32 +0600 Subject: [PATCH 3/5] Revert "start moving to kotlinx-io" This reverts commit 52157ee0e7f3d4dca66a32a71c3d597dac5c881a. --- common/build.gradle | 1 - .../dev/inmo/micro_utils/common/MPPFile.kt | 35 +++---------------- gradle/libs.versions.toml | 3 -- 3 files changed, 5 insertions(+), 34 deletions(-) diff --git a/common/build.gradle b/common/build.gradle index d4fc46ec83d..01489bbf4f1 100644 --- a/common/build.gradle +++ b/common/build.gradle @@ -11,7 +11,6 @@ kotlin { commonMain { dependencies { api libs.klock - api libs.kt.io } } jvmMain { diff --git a/common/src/commonMain/kotlin/dev/inmo/micro_utils/common/MPPFile.kt b/common/src/commonMain/kotlin/dev/inmo/micro_utils/common/MPPFile.kt index fd397e0d811..7aef8ed8c9a 100644 --- a/common/src/commonMain/kotlin/dev/inmo/micro_utils/common/MPPFile.kt +++ b/common/src/commonMain/kotlin/dev/inmo/micro_utils/common/MPPFile.kt @@ -1,11 +1,5 @@ package dev.inmo.micro_utils.common -import kotlinx.io.Buffer -import kotlinx.io.Source -import kotlinx.io.buffered -import kotlinx.io.files.Path -import kotlinx.io.files.SystemFileSystem -import kotlinx.io.readByteArray import kotlinx.serialization.Serializable import kotlin.jvm.JvmInline @@ -29,31 +23,12 @@ value class FileName(val string: String) { } -typealias MPPFile = Path +expect class MPPFile -val MPPFile.filename: FileName - get() = FileName(name) -val MPPFile.filesize: Long - get() = SystemFileSystem.metadataOrNull(this) ?.size ?.takeIf { it > -1 } ?: error("Path $filename does not exists or is folder") -val MPPFile.bytesAllocatorSync: ByteArrayAllocator - get() = { - source().readByteArray() - } -val MPPFile.bytesAllocator: SuspendByteArrayAllocator - get() = { - bytesAllocatorSync() - } +expect val MPPFile.filename: FileName +expect val MPPFile.filesize: Long +expect val MPPFile.bytesAllocatorSync: ByteArrayAllocator +expect val MPPFile.bytesAllocator: SuspendByteArrayAllocator fun MPPFile.bytesSync() = bytesAllocatorSync() suspend fun MPPFile.bytes() = bytesAllocator() -fun MPPFile.source(): Source = SystemFileSystem.source(this).buffered() - - -//expect class MPPFile -// -//expect val MPPFile.filename: FileName -//expect val MPPFile.filesize: Long -//expect val MPPFile.bytesAllocatorSync: ByteArrayAllocator -//expect val MPPFile.bytesAllocator: SuspendByteArrayAllocator -//fun MPPFile.bytesSync() = bytesAllocatorSync() -//suspend fun MPPFile.bytes() = bytesAllocator() diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index e68dec8a2d6..84313b0b175 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -4,8 +4,6 @@ kt = "1.9.23" kt-serialization = "1.6.3" kt-coroutines = "1.8.1" -kt-io = "0.5.1" - kslog = "1.3.4" jb-compose = "1.6.2" @@ -55,7 +53,6 @@ kt-coroutines = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", vers kt-coroutines-android = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android", version.ref = "kt-coroutines" } kt-coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "kt-coroutines" } -kt-io = { module = "org.jetbrains.kotlinx:kotlinx-io-core", version.ref = "kt-io" } ktor-io = { module = "io.ktor:ktor-io", version.ref = "ktor" } ktor-serialization-kotlinx-json = { module = "io.ktor:ktor-serialization-kotlinx-json", version.ref = "ktor" } From 698ed6718d8b6517a26d0a9a16d5ba9f41f341bc Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Thu, 25 Jul 2024 02:27:33 +0600 Subject: [PATCH 4/5] improve sealed workaround generation --- .../src/main/kotlin/WalkOnKSFiles.kt | 30 +++++++++++++++ .../generator/src/main/kotlin/Processor.kt | 37 ++++++++++++++----- .../kotlin/GenerateSealedWorkaround.kt | 3 +- 3 files changed, 60 insertions(+), 10 deletions(-) create mode 100644 ksp/generator/src/main/kotlin/WalkOnKSFiles.kt diff --git a/ksp/generator/src/main/kotlin/WalkOnKSFiles.kt b/ksp/generator/src/main/kotlin/WalkOnKSFiles.kt new file mode 100644 index 00000000000..8634cf815b7 --- /dev/null +++ b/ksp/generator/src/main/kotlin/WalkOnKSFiles.kt @@ -0,0 +1,30 @@ +package dev.inmo.micro_ksp.generator + +import com.google.devtools.ksp.getAllSuperTypes +import com.google.devtools.ksp.symbol.KSAnnotated +import com.google.devtools.ksp.symbol.KSClassDeclaration +import com.google.devtools.ksp.symbol.KSDeclarationContainer +import com.google.devtools.ksp.symbol.KSFile + +fun KSClassDeclaration.findSubClasses(subSymbol: KSAnnotated): Sequence { + return when (subSymbol) { + is KSClassDeclaration -> if (subSymbol.getAllSuperTypes().map { it.declaration }.contains(this)) { + sequenceOf(subSymbol) + } else { + sequenceOf() + } + else -> sequenceOf() + } + if (subSymbol is KSDeclarationContainer) { + subSymbol.declarations.flatMap { + findSubClasses(it) + } + } else { + sequenceOf() + } +} + +fun KSClassDeclaration.findSubClasses(files: Sequence): Sequence { + return files.flatMap { + findSubClasses(it) + } +} diff --git a/ksp/sealed/generator/src/main/kotlin/Processor.kt b/ksp/sealed/generator/src/main/kotlin/Processor.kt index e8816e7bb14..de653834d08 100644 --- a/ksp/sealed/generator/src/main/kotlin/Processor.kt +++ b/ksp/sealed/generator/src/main/kotlin/Processor.kt @@ -6,7 +6,6 @@ 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.AnnotationSpec import com.squareup.kotlinpoet.ClassName import com.squareup.kotlinpoet.CodeBlock import com.squareup.kotlinpoet.FileSpec @@ -16,18 +15,34 @@ 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.findSubClasses import dev.inmo.micro_ksp.generator.writeFile import dev.inmo.microutils.kps.sealed.GenerateSealedWorkaround +import java.io.File class Processor( private val codeGenerator: CodeGenerator ) : SymbolProcessor { - private fun KSClassDeclaration.resolveSubclasses(): List { - return (getSealedSubclasses().flatMap { - it.resolveSubclasses() - }.ifEmpty { - sequenceOf(this) - }).toList() + private fun KSClassDeclaration.findSealedConnection(potentialSealedParent: KSClassDeclaration): Boolean { + val targetClassname = potentialSealedParent.qualifiedName ?.asString() + return superTypes.any { + targetClassname == ((it.resolve().declaration as? KSClassDeclaration) ?.qualifiedName ?.asString()) || (it is KSClassDeclaration && it.getSealedSubclasses().any() && it.findSealedConnection(potentialSealedParent)) + } + } + + private fun KSClassDeclaration.resolveSubclasses( + searchIn: Sequence, + allowNonSealed: Boolean + ): Sequence { + return findSubClasses(searchIn).let { + if (allowNonSealed) { + it + } else { + it.filter { + it.findSealedConnection(this) + } + } + } } @OptIn(KspExperimental::class) @@ -35,7 +50,11 @@ class Processor( ksClassDeclaration: KSClassDeclaration, resolver: Resolver ) { - val subClasses = ksClassDeclaration.resolveSubclasses().distinct() + val annotation = ksClassDeclaration.getAnnotationsByType(GenerateSealedWorkaround::class).first() + val subClasses = ksClassDeclaration.resolveSubclasses( + searchIn = resolver.getAllFiles(), + allowNonSealed = annotation.includeNonSealedSubTypes + ).distinct() val subClassesNames = subClasses.filter { when (it.classKind) { ClassKind.ENUM_ENTRY, @@ -51,7 +70,7 @@ class Processor( (it.getAnnotationsByType(GenerateSealedWorkaround.Order::class).firstOrNull()) ?.order ?: 0 }.map { it.toClassName() - } + }.toList() val className = ksClassDeclaration.toClassName() val setType = Set::class.asTypeName().parameterizedBy( ksClassDeclaration.toClassName() diff --git a/ksp/sealed/src/commonMain/kotlin/GenerateSealedWorkaround.kt b/ksp/sealed/src/commonMain/kotlin/GenerateSealedWorkaround.kt index 0dcf29fb50c..c98eed90d8e 100644 --- a/ksp/sealed/src/commonMain/kotlin/GenerateSealedWorkaround.kt +++ b/ksp/sealed/src/commonMain/kotlin/GenerateSealedWorkaround.kt @@ -3,7 +3,8 @@ package dev.inmo.microutils.kps.sealed @Retention(AnnotationRetention.BINARY) @Target(AnnotationTarget.CLASS) annotation class GenerateSealedWorkaround( - val prefix: String = "" + val prefix: String = "", + val includeNonSealedSubTypes: Boolean = false ) { @Retention(AnnotationRetention.BINARY) @Target(AnnotationTarget.CLASS) From 481130c9bb5b4e0f05bac41c79118db2937764ad Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Thu, 25 Jul 2024 02:30:10 +0600 Subject: [PATCH 5/5] fill changelog --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d419a93774..7073379f1b5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ ## 0.21.5 +* `KSP`: + * Add utility functions `KSClassDeclaration.findSubClasses` + * `Sealed`: + * Improve generation + ## 0.21.4 * `Common`: