From bd15b6ae0eee685c1b8608f7d44c71122552fc25 Mon Sep 17 00:00:00 2001 From: ForteScarlet Date: Mon, 12 Aug 2024 17:32:13 +0800 Subject: [PATCH] =?UTF-8?q?optimize(internal):=20=E7=AE=80=E5=8D=95?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=86=85=E9=83=A8=E7=9A=84KSP?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../apireader/ApiReaderProcessor.kt | 56 +++--- .../apireader/EventReaderProcessor.kt | 52 +++--- .../build.gradle.kts | 166 ------------------ 3 files changed, 60 insertions(+), 214 deletions(-) delete mode 100644 simbot-component-kook-stdlib-test/build.gradle.kts diff --git a/internal-processors/api-reader/src/main/kotlin/kook/internal/processors/apireader/ApiReaderProcessor.kt b/internal-processors/api-reader/src/main/kotlin/kook/internal/processors/apireader/ApiReaderProcessor.kt index 8977ada5..244eeee7 100644 --- a/internal-processors/api-reader/src/main/kotlin/kook/internal/processors/apireader/ApiReaderProcessor.kt +++ b/internal-processors/api-reader/src/main/kotlin/kook/internal/processors/apireader/ApiReaderProcessor.kt @@ -20,8 +20,7 @@ package kook.internal.processors.apireader -import com.google.devtools.ksp.KspExperimental -import com.google.devtools.ksp.getKotlinClassByName +import com.google.devtools.ksp.getClassDeclarationByName import com.google.devtools.ksp.isAbstract import com.google.devtools.ksp.processing.Resolver import com.google.devtools.ksp.processing.SymbolProcessor @@ -42,29 +41,11 @@ abstract class ReaderProcessor(private val environment: SymbolProcessorEnvironme abstract val optionName: String abstract val targetClassName: String - @OptIn(KspExperimental::class) - override fun process(resolver: Resolver): List { - val targetFilePath: String? = environment.options[optionName] - - val targetFile = File(targetFilePath ?: run { - val msg = "target output file option ['$optionName'] is null!" - environment.logger.warn(msg) - return emptyList() - }) - - environment.logger.info("target output file: ${targetFile.absolutePath}") - val targetClass = resolver.getKotlinClassByName(targetClassName) - environment.logger.info("apiClass: $targetClassName") - targetClass ?: return emptyList() - - val targetClasses = resolver.getAllFiles().flatMap { it.declarations } - .filterIsInstance() - .filter { - targetClass.asStarProjectedType().isAssignableFrom(it.asStarProjectedType()) - } - .filter { !it.isAbstract() } - .toList() + private var targetFile: File? = null + private val targetClasses = mutableListOf() + override fun finish() { + val targetFile = targetFile ?: return if (!targetFile.exists()) { targetFile.parentFile.mkdirs() } else { @@ -80,7 +61,32 @@ abstract class ReaderProcessor(private val environment: SymbolProcessorEnvironme ).use { writer -> writer.writeDeflistTo(targetClasses) } + } + override fun process(resolver: Resolver): List { + val targetFilePath: String? = environment.options[optionName] + + val targetFile = File(targetFilePath ?: run { + val msg = "target output file option ['$optionName'] is null!" + environment.logger.warn(msg) + return emptyList() + }) + + this.targetFile = targetFile + + environment.logger.info("target output file: ${targetFile.absolutePath}") + val targetClass = resolver.getClassDeclarationByName(targetClassName) + environment.logger.info("apiClass: $targetClassName found $targetClass", targetClass) + targetClass ?: return emptyList() + + // find all + resolver.getAllFiles().flatMap { it.declarations } + .filterIsInstance() + .filter { + targetClass.asStarProjectedType().isAssignableFrom(it.asStarProjectedType()) + } + .filter { !it.isAbstract() } + .toCollection(targetClasses) return emptyList() } @@ -91,7 +97,7 @@ abstract class ReaderProcessor(private val environment: SymbolProcessorEnvironme * * @author ForteScarlet */ -class ApiReaderProcessor(private val environment: SymbolProcessorEnvironment) : ReaderProcessor(environment) { +class ApiReaderProcessor(environment: SymbolProcessorEnvironment) : ReaderProcessor(environment) { override val optionName: String = API_READ_TARGET_FILE_OPTION_KEY override val targetClassName: String = KOOK_API_CLASS_NAME } diff --git a/internal-processors/api-reader/src/main/kotlin/kook/internal/processors/apireader/EventReaderProcessor.kt b/internal-processors/api-reader/src/main/kotlin/kook/internal/processors/apireader/EventReaderProcessor.kt index 92b50f05..631be054 100644 --- a/internal-processors/api-reader/src/main/kotlin/kook/internal/processors/apireader/EventReaderProcessor.kt +++ b/internal-processors/api-reader/src/main/kotlin/kook/internal/processors/apireader/EventReaderProcessor.kt @@ -20,8 +20,7 @@ package kook.internal.processors.apireader -import com.google.devtools.ksp.KspExperimental -import com.google.devtools.ksp.getKotlinClassByName +import com.google.devtools.ksp.getClassDeclarationByName import com.google.devtools.ksp.getVisibility import com.google.devtools.ksp.processing.Resolver import com.google.devtools.ksp.processing.SymbolProcessor @@ -50,7 +49,29 @@ class EventReaderProcessor(private val environment: SymbolProcessorEnvironment) private val targetClassName = environment.options[EVENT_READ_TARGET_CLASS_OPTION_KEY] ?: KOOK_EVENT_CLASS_NAME - @OptIn(KspExperimental::class) + private var targetFile: File? = null + private val targetClasses = mutableListOf() + + override fun finish() { + val targetFile = targetFile ?: return + + if (!targetFile.exists()) { + targetFile.parentFile.mkdirs() + } else { + targetFile.delete() + } + + targetFile.toPath().bufferedWriter( + options = arrayOf( + StandardOpenOption.WRITE, + StandardOpenOption.TRUNCATE_EXISTING, + StandardOpenOption.CREATE + ) + ).use { writer -> + writer.writeDeflistTo(targetClasses) + } + } + override fun process(resolver: Resolver): List { val targetFilePath: String? = environment.options[EVENT_READ_TARGET_FILE_OPTION_KEY] @@ -59,37 +80,22 @@ class EventReaderProcessor(private val environment: SymbolProcessorEnvironment) environment.logger.warn(msg) return emptyList() }) + this.targetFile = targetFile environment.logger.info("Target class name: $targetClassName") environment.logger.info("Target output file: ${targetFile.absolutePath}") - val targetClass = resolver.getKotlinClassByName(targetClassName) - environment.logger.info("apiClass: $targetClass") + val targetClass = resolver.getClassDeclarationByName(targetClassName) + environment.logger.info("apiClass: $targetClass found at $targetClass", targetClass) targetClass ?: return emptyList() - val targetClasses = resolver.getAllFiles().flatMap { it.declarations } + resolver.getAllFiles().flatMap { it.declarations } .filterIsInstance() .filter { targetClass.asStarProjectedType().isAssignableFrom(it.asStarProjectedType()) } // .filter { !it.isAbstract() } .filter { it.getVisibility() in EXPECT_VISIBILITY } - .toList() - - if (!targetFile.exists()) { - targetFile.parentFile.mkdirs() - } else { - targetFile.delete() - } - - targetFile.toPath().bufferedWriter( - options = arrayOf( - StandardOpenOption.WRITE, - StandardOpenOption.TRUNCATE_EXISTING, - StandardOpenOption.CREATE - ) - ).use { writer -> - writer.writeDeflistTo(targetClasses) - } + .toCollection(targetClasses) return emptyList() } diff --git a/simbot-component-kook-stdlib-test/build.gradle.kts b/simbot-component-kook-stdlib-test/build.gradle.kts deleted file mode 100644 index 36a4777c..00000000 --- a/simbot-component-kook-stdlib-test/build.gradle.kts +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright (c) 2023. ForteScarlet. - * - * This file is part of simbot-component-kook. - * - * simbot-component-kook is free software: you can redistribute it and/or modify it under the terms of - * the GNU Lesser General Public License as published by the Free Software Foundation, - * either version 3 of the License, or (at your option) any later version. - * - * simbot-component-kook is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License along with simbot-component-kook, - * If not, see . - */ - -import love.forte.gradle.common.kotlin.multiplatform.NativeTargets - -plugins { - kotlin("multiplatform") - kotlin("plugin.serialization") -} - - -repositories { - mavenCentral() -} - -kotlin { - jvm { - withJava() - compilations.all { - kotlinOptions { - jvmTarget = "1.8" - javaParameters = true - freeCompilerArgs = freeCompilerArgs + listOf("-Xjvm-default=all") - } - } - testRuns["test"].executionTask.configure { - useJUnitPlatform() - } - } - - js(IR) { - nodejs { - } - binaries.executable() - } - - - val mainPresets = mutableSetOf() - val testPresets = mutableSetOf() - - // see https://kotlinlang.org/docs/native-target-suppors - - val targets = NativeTargets.Official.all.intersect(NativeTargets.KtorClient.all) - - targets { - presets.filterIsInstance>() - .filter { it.name in targets } - .forEach { presets -> - val target = fromPreset(presets, presets.name) - val mainSourceSet = target.compilations["main"].kotlinSourceSets.first() - val testSourceSet = target.compilations["test"].kotlinSourceSets.first() - - val tn = target.name - when { - // just for test - // main中只使用HttpClient但用不到引擎,没必要指定 - - // win - tn.startsWith("mingw") -> { - mainSourceSet.dependencies { - implementation(libs.ktor.client.winhttp) - } - } - // linux: CIO..? - tn.startsWith("linux") -> { - mainSourceSet.dependencies { - implementation(libs.ktor.client.cio) - } - } - - // darwin based - tn.startsWith("macos") - || tn.startsWith("ios") - || tn.startsWith("watchos") - || tn.startsWith("tvos") -> { - mainSourceSet.dependencies { - implementation(libs.ktor.client.darwin) - } - } - } - - mainPresets.add(mainSourceSet) - testPresets.add(testSourceSet) - } - } - - sourceSets { - val commonMain by getting { - dependencies { - api(project(":simbot-component-kook-stdlib-multi")) - } - } - - val commonTest by getting { - dependencies { - implementation(kotlin("test")) - implementation(libs.kotlinx.coroutines.test) - } - } - - val jvmMain by getting { - dependencies { - runtimeOnly(libs.ktor.client.cio) - compileOnly(simbotUtilAnnotations) // use @Api4J annotation - } - } - - - getByName("jvmTest") { - dependencies { - implementation(libs.ktor.client.cio) - implementation(simbotApi) - implementation(simbotLogger) - implementation(simbotLoggerSlf4j) - } - } - - getByName("jsMain") { - dependencies { - implementation(libs.ktor.client.js) - implementation("love.forte.plugin.suspend-transform:suspend-transform-annotation:0.4.0") - } - } - - val nativeMain by creating { - dependsOn(commonMain) - } - - val nativeTest by creating { - dependsOn(commonTest) - } - - configure(mainPresets) { dependsOn(nativeMain) } - configure(testPresets) { dependsOn(nativeTest) } - - } - -} - - - -// suppress all? -//tasks.withType().configureEach { -// dokkaSourceSets.configureEach { -// suppress.set(true) -// perPackageOption { -// suppress.set(true) -// } -// } -//} - -