Skip to content

Commit 2954697

Browse files
authored
Merge pull request #1013 from simple-robot/processor-class-builder
增加辅助用KSP处理器模块 processor-class-builder
2 parents 654371b + 7b7f024 commit 2954697

File tree

22 files changed

+1928
-19
lines changed

22 files changed

+1928
-19
lines changed

build.gradle.kts

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323

2424
import changelog.createSubChangelogFile
2525
import changelog.generateChangelog
26-
import io.gitlab.arturbosch.detekt.Detekt
2726
import love.forte.plugin.suspendtrans.*
2827
import love.forte.plugin.suspendtrans.gradle.SuspendTransformGradleExtension
2928
import org.jetbrains.dokka.gradle.engine.parameters.DokkaSourceSetSpec
@@ -87,10 +86,6 @@ subprojects {
8786
}
8887

8988
afterEvaluate {
90-
if (plugins.hasPlugin("io.gitlab.arturbosch.detekt")) {
91-
return@afterEvaluate
92-
}
93-
9489
applyKover(root)
9590

9691
if (plugins.hasPlugin(libs.plugins.suspendTransform.get().pluginId)) {
@@ -118,7 +113,7 @@ detekt {
118113
}
119114

120115
// https://detekt.dev/blog/2019/03/03/configure-detekt-on-root-project/
121-
tasks.withType<Detekt>().configureEach {
116+
tasks.detekt {
122117
// internal 处理器不管
123118
exclude("internal-processors/**")
124119
// tests 不管
@@ -159,12 +154,13 @@ fun Project.applyKover(rp: Project) {
159154
apiValidation {
160155
ignoredPackages.add("*.internal.*")
161156

162-
this.ignoredProjects.addAll(
157+
ignoredProjects.addAll(
163158
listOf(
164159
"interface-uml-processor",
165160
"simbot-test",
166161
"tests",
167162
"spring-boot-starter-test",
163+
"simbot-processor-class-builder-test"
168164
)
169165
)
170166

buildSrc/src/main/kotlin/JVMConstants.kt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
/*
2-
* Copyright (c) 2024. ForteScarlet.
2+
* Copyright (c) 2024-2025. ForteScarlet.
33
*
44
* Project https://github.com/simple-robot/simpler-robot
55
66
*
7-
* This file is part of the Simple Robot Library.
7+
* This file is part of the Simple Robot Library (Alias: simple-robot, simbot, etc.).
88
*
99
* This program is free software: you can redistribute it and/or modify
1010
* it under the terms of the GNU Lesser General Public License as published by
@@ -24,4 +24,7 @@
2424
object JVMConstants {
2525
const val KT_JVM_TARGET_VALUE = 11
2626
const val KT_JVM_TARGET = "11"
27+
28+
const val TARGET_1_8_VALUE = 8
29+
const val TARGET_1_8 = "1.8"
2730
}

buildSrc/src/main/kotlin/JvmConfig.kt

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2024. ForteScarlet.
2+
* Copyright (c) 2024-2025. ForteScarlet.
33
*
44
* Project https://github.com/simple-robot/simpler-robot
55
@@ -75,7 +75,12 @@ inline fun KotlinJvmProjectExtension.configKotlinJvm(
7575
configJavaToolchain(jdkVersion)
7676
compilerOptions {
7777
javaParameters.set(true)
78-
jvmTarget.set(JvmTarget.fromTarget(jdkVersion.toString()))
78+
jvmTarget.set(
79+
when (jdkVersion) {
80+
8 -> JvmTarget.JVM_1_8
81+
else -> JvmTarget.fromTarget(jdkVersion.toString())
82+
}
83+
)
7984
// freeCompilerArgs.addAll("-Xjvm-default=all", "-Xjsr305=strict")
8085
freeCompilerArgs.set(freeCompilerArgs.getOrElse(emptyList()) + listOf("-Xjvm-default=all", "-Xjsr305=strict"))
8186
}

settings.gradle.kts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ include(":simbot-gradles:simbot-gradle-suspendtransforms")
4545

4646
// processors
4747
include("simbot-processors:simbot-processor-message-element-polymorphic-include")
48+
include("simbot-processors:class-builder:simbot-processor-class-builder")
49+
include("simbot-processors:class-builder:simbot-processor-class-builder-annotation")
50+
include("simbot-processors:class-builder:simbot-processor-class-builder-test")
4851

4952
include(":simbot-commons:simbot-common-annotations")
5053
include(":simbot-commons:simbot-common-collection")

simbot-api/src/jvmTest/java/ResourceTests.java

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
/*
2-
* Copyright (c) 2024. ForteScarlet.
2+
* Copyright (c) 2024-2025. ForteScarlet.
33
*
44
* Project https://github.com/simple-robot/simpler-robot
55
66
*
7-
* This file is part of the Simple Robot Library.
7+
* This file is part of the Simple Robot Library (Alias: simple-robot, simbot, etc.).
88
*
99
* This program is free software: you can redistribute it and/or modify
1010
* it under the terms of the GNU Lesser General Public License as published by
@@ -21,20 +21,26 @@
2121
*
2222
*/
2323

24-
import love.forte.simbot.message.OfflineImage;
2524
import love.forte.simbot.resource.Resources;
25+
import love.forte.simbot.resource.SourceResource;
26+
import org.junit.jupiter.api.Assertions;
27+
import org.junit.jupiter.api.Test;
2628

2729
import java.io.File;
2830
import java.io.IOException;
31+
import java.nio.file.Paths;
2932

3033
/**
3134
* @author ForteScarlet
3235
*/
3336
public class ResourceTests {
34-
public static void main(String[] args) throws IOException {
35-
OfflineImage.ofResource(Resources.valueOf(File.createTempFile("", "")));
36-
3737

38+
@Test
39+
public void testResourceCreation() throws IOException {
40+
var fr = Resources.valueOf(new File("test"));
41+
var pr = Resources.valueOf(Paths.get("test.txt"));
3842

43+
Assertions.assertInstanceOf(SourceResource.class, fr);
44+
Assertions.assertInstanceOf(SourceResource.class, pr);
3945
}
4046
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# simbot-processor-class-builder
2+
3+
为 Kotlin 中的某个 `class` 生成一个 Builder。
4+
5+
例如:
6+
7+
```kotlin
8+
class Person(
9+
val name: String,
10+
val age: Int
11+
) {
12+
var size: Int? = null
13+
}
14+
```
15+
16+
生成:
17+
18+
```Kotlin
19+
@BuilderFor(Person::class)
20+
class PersonBuilder {
21+
22+
private lateinit var name: String
23+
private var age: Int by kotlin.properties.Delegates.notNull()
24+
private var size: Int? = null
25+
26+
public fun name(name: String): PersonBuilder = apply {
27+
this.name = name
28+
}
29+
30+
// other functions...
31+
32+
public fun build(): Person {
33+
return Person(
34+
name = name,
35+
age = age,
36+
).also {
37+
size?.also { p0 -> it.size = p0 }
38+
}
39+
}
40+
}
41+
```
42+
43+
特性:
44+
45+
-`null` 属性通过 `lateinit var``Delegates.notNull()` 进行处理。
46+
- List、Set、Map 等集合属性会生成 `add``addAll``clear` 等方法。
47+
- 如果属性也可能存在一个 `Builder`(找到了带有 `BuilderFor` 的 Builder),生成 `inline``block: XxxBuilder.() -> Unit`
48+
DSL 扩展API。
49+
- List、Set、Map (value) 的元素如果也可能存在一个 `Builder`,生成 `inline``block: XxxBuilder.() -> Unit` DSL 扩展API。
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
public abstract interface annotation class love/forte/simbot/processor/classbuilder/annotation/BuilderFor : java/lang/annotation/Annotation {
2+
public abstract fun value ()Ljava/lang/Class;
3+
}
4+
5+
public abstract interface annotation class love/forte/simbot/processor/classbuilder/annotation/ClassBuilder : java/lang/annotation/Annotation {
6+
public abstract fun internal ()Z
7+
public abstract fun marks ()[Ljava/lang/Class;
8+
public abstract fun name ()Ljava/lang/String;
9+
public abstract fun open ()Z
10+
}
11+
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Copyright (c) 2024-2025. ForteScarlet.
3+
*
4+
* Project https://github.com/simple-robot/simpler-robot
5+
6+
*
7+
* This file is part of the Simple Robot Library (Alias: simple-robot, simbot, etc.).
8+
*
9+
* This program is free software: you can redistribute it and/or modify
10+
* it under the terms of the GNU Lesser General Public License as published by
11+
* the Free Software Foundation, either version 3 of the License, or
12+
* (at your option) any later version.
13+
*
14+
* This program is distributed in the hope that it will be useful,
15+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+
* Lesser GNU General Public License for more details.
18+
*
19+
* You should have received a copy of the Lesser GNU General Public License
20+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
21+
*
22+
*/
23+
24+
plugins {
25+
kotlin("jvm")
26+
id("org.jetbrains.dokka")
27+
}
28+
29+
configJavaCompileWithModule(
30+
moduleName = "simbot.processor.classbuilder.annotation",
31+
jvmVersion = JVMConstants.KT_JVM_TARGET
32+
)
33+
apply(plugin = "simbot-jvm-maven-publish")
34+
35+
kotlin {
36+
explicitApi()
37+
configKotlinJvm(JVMConstants.KT_JVM_TARGET_VALUE)
38+
}
39+
40+
tasks.getByName<Test>("test") {
41+
useJUnitPlatform()
42+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
module simbot.processor.classbuilder.annotation {
2+
requires kotlin.stdlib;
3+
exports love.forte.simbot.processor.classbuilder.annotation;
4+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
* Copyright (c) 2025. ForteScarlet.
3+
*
4+
* Project https://github.com/simple-robot/simpler-robot
5+
6+
*
7+
* This file is part of the Simple Robot Library (Alias: simple-robot, simbot, etc.).
8+
*
9+
* This program is free software: you can redistribute it and/or modify
10+
* it under the terms of the GNU Lesser General Public License as published by
11+
* the Free Software Foundation, either version 3 of the License, or
12+
* (at your option) any later version.
13+
*
14+
* This program is distributed in the hope that it will be useful,
15+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+
* Lesser GNU General Public License for more details.
18+
*
19+
* You should have received a copy of the Lesser GNU General Public License
20+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
21+
*
22+
*/
23+
24+
package love.forte.simbot.processor.classbuilder.annotation
25+
26+
import kotlin.reflect.KClass
27+
28+
@Retention(AnnotationRetention.BINARY)
29+
@Target(AnnotationTarget.CLASS)
30+
public annotation class BuilderFor(val value: KClass<*>)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
* Copyright (c) 2025. ForteScarlet.
3+
*
4+
* Project https://github.com/simple-robot/simpler-robot
5+
6+
*
7+
* This file is part of the Simple Robot Library (Alias: simple-robot, simbot, etc.).
8+
*
9+
* This program is free software: you can redistribute it and/or modify
10+
* it under the terms of the GNU Lesser General Public License as published by
11+
* the Free Software Foundation, either version 3 of the License, or
12+
* (at your option) any later version.
13+
*
14+
* This program is distributed in the hope that it will be useful,
15+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+
* Lesser GNU General Public License for more details.
18+
*
19+
* You should have received a copy of the Lesser GNU General Public License
20+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
21+
*
22+
*/
23+
24+
package love.forte.simbot.processor.classbuilder.annotation
25+
26+
import kotlin.reflect.KClass
27+
28+
@Retention(AnnotationRetention.BINARY)
29+
@Target(AnnotationTarget.CLASS)
30+
public annotation class ClassBuilder(
31+
/**
32+
* 生成的 builder 的类名。
33+
* 默认为 `原类名 + "Builder"`
34+
*/
35+
val name: String = "",
36+
/**
37+
* 需要添加的额外标记注解。
38+
*/
39+
val marks: Array<KClass<out Annotation>> = [],
40+
/**
41+
* Open Builder and all functions.
42+
* Default is `false`.
43+
*/
44+
val open: Boolean = false,
45+
46+
/**
47+
* The builder is `internal`.
48+
* If `false`, the builder is `public`.
49+
*/
50+
val internal: Boolean = false,
51+
)
52+
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Copyright (c) 2024-2025. ForteScarlet.
3+
*
4+
* Project https://github.com/simple-robot/simpler-robot
5+
6+
*
7+
* This file is part of the Simple Robot Library (Alias: simple-robot, simbot, etc.).
8+
*
9+
* This program is free software: you can redistribute it and/or modify
10+
* it under the terms of the GNU Lesser General Public License as published by
11+
* the Free Software Foundation, either version 3 of the License, or
12+
* (at your option) any later version.
13+
*
14+
* This program is distributed in the hope that it will be useful,
15+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+
* Lesser GNU General Public License for more details.
18+
*
19+
* You should have received a copy of the Lesser GNU General Public License
20+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
21+
*
22+
*/
23+
24+
plugins {
25+
kotlin("jvm")
26+
alias(libs.plugins.ksp)
27+
}
28+
29+
configJavaCompileWithModule(jvmVersion = JVMConstants.KT_JVM_TARGET)
30+
31+
kotlin {
32+
configKotlinJvm(JVMConstants.KT_JVM_TARGET_VALUE)
33+
}
34+
35+
dependencies {
36+
testImplementation(kotlin("test-junit5"))
37+
testImplementation(project(":simbot-processors:class-builder:simbot-processor-class-builder-annotation"))
38+
kspTest(project(":simbot-processors:class-builder:simbot-processor-class-builder"))
39+
}
40+
41+
tasks.getByName<Test>("test") {
42+
useJUnitPlatform()
43+
}

0 commit comments

Comments
 (0)