From 0ab221290063d0c3d3f678987a6d333b861944bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A6=82=E6=A2=A6=E6=8A=80=E6=9C=AF?= <596392912@qq.com> Date: Tue, 28 May 2024 11:09:48 +0800 Subject: [PATCH] =?UTF-8?q?:sparkles:=20=E8=AF=95=E7=8E=A9=20kotlin=20ksp?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 17 ++- .../auto/service/AutoServiceProcessor.java | 2 +- .../service/AutoServiceSymbolProcessor.java | 104 ++++++++++++++++ .../AutoServiceSymbolProcessorProvider.java | 39 ++++++ .../AutoServiceSymbolProcessorTest.java | 112 ++++++++++++++++++ 5 files changed, 270 insertions(+), 4 deletions(-) create mode 100644 src/main/java/net/dreamlu/mica/auto/service/AutoServiceSymbolProcessor.java create mode 100644 src/main/java/net/dreamlu/mica/auto/service/AutoServiceSymbolProcessorProvider.java create mode 100644 src/test/java/net/dreamlu/mica/auto/service/AutoServiceSymbolProcessorTest.java diff --git a/build.gradle b/build.gradle index 83d2282..fcf456f 100644 --- a/build.gradle +++ b/build.gradle @@ -1,19 +1,23 @@ -apply plugin: "java-library" +plugins { + id 'java-library' + id 'org.jetbrains.kotlin.jvm' version '1.9.24' apply false +} apply from: "${rootProject.projectDir}/gradle/publish-maven.gradle" ext { javaVersion = JavaVersion.VERSION_1_8 springBootVersion = "2.7.18" - lombokVersion = "1.18.30" + lombokVersion = "1.18.32" googleAutoVersion = "1.1.1" compileTestingVersion = '0.21.0' inCapVersion = "1.0.0" + kotlinVersion = "1.9.24" } group = GROUPID version = VERSION -allprojects { +projects { apply plugin: 'java' sourceCompatibility = javaVersion targetCompatibility = javaVersion @@ -27,6 +31,7 @@ tasks.withType(JavaCompile) { dependencies { api "org.springframework.boot:spring-boot-configuration-processor:$springBootVersion" api "org.springframework.boot:spring-boot-autoconfigure-processor:$springBootVersion" + implementation("com.google.devtools.ksp:symbol-processing-api:1.9.24-1.0.20") compileOnly "org.projectlombok:lombok:$lombokVersion" annotationProcessor "org.projectlombok:lombok:$lombokVersion" compileOnly "com.google.auto.service:auto-service:$googleAutoVersion" @@ -35,6 +40,12 @@ dependencies { annotationProcessor "net.ltgt.gradle.incap:incap-processor:$inCapVersion" testImplementation "com.google.testing.compile:compile-testing:$compileTestingVersion" testImplementation "net.ltgt.gradle.incap:incap:$inCapVersion" + testImplementation 'dev.zacsweers.kctfork:ksp:0.4.1' + testImplementation "org.jetbrains.kotlin:kotlin-compiler-embeddable:$kotlinVersion" + testImplementation "org.jetbrains.kotlin:kotlin-scripting-compiler:$kotlinVersion" + testImplementation "org.jetbrains.kotlin:kotlin-scripting-compiler-impl:$kotlinVersion" + testImplementation "org.jetbrains.kotlin:kotlin-scripting-common:$kotlinVersion" + testImplementation "org.jetbrains.kotlin:kotlin-scripting-jvm:$kotlinVersion" } repositories { diff --git a/src/main/java/net/dreamlu/mica/auto/service/AutoServiceProcessor.java b/src/main/java/net/dreamlu/mica/auto/service/AutoServiceProcessor.java index 1505775..31ba83f 100644 --- a/src/main/java/net/dreamlu/mica/auto/service/AutoServiceProcessor.java +++ b/src/main/java/net/dreamlu/mica/auto/service/AutoServiceProcessor.java @@ -48,7 +48,7 @@ public class AutoServiceProcessor extends AbstractMicaProcessor { /** * AutoService 注解名 */ - private static final String AUTO_SERVICE_NAME = net.dreamlu.mica.auto.annotation.AutoService.class.getName(); + public static final String AUTO_SERVICE_NAME = net.dreamlu.mica.auto.annotation.AutoService.class.getName(); /** * spi 服务集合,key 接口 -> value 实现列表 */ diff --git a/src/main/java/net/dreamlu/mica/auto/service/AutoServiceSymbolProcessor.java b/src/main/java/net/dreamlu/mica/auto/service/AutoServiceSymbolProcessor.java new file mode 100644 index 0000000..19bfb63 --- /dev/null +++ b/src/main/java/net/dreamlu/mica/auto/service/AutoServiceSymbolProcessor.java @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & www.dreamlu.net). + *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *
+ * http://www.gnu.org/licenses/lgpl.html + *
+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.dreamlu.mica.auto.service; + +import com.google.common.collect.HashMultimap; +import com.google.common.collect.Multimap; +import com.google.devtools.ksp.processing.*; +import com.google.devtools.ksp.symbol.*; +import kotlin.Pair; +import kotlin.sequences.Sequence; +import org.jetbrains.annotations.NotNull; + +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + + +/** + * ksp AutoService 处理器 + * + * @author L.cm + */ +public class AutoServiceSymbolProcessor implements SymbolProcessor { + private final SymbolProcessorEnvironment environment; + private final CodeGenerator codeGenerator; + private final KSPLogger logger; + + /** + * Maps the class names of service provider interfaces to the class names of the concrete classes + * which implement them plus their KSFile (for incremental processing). + *
+ * For example,
+ * ```
+ * "com.google.apphosting.LocalRpcService" -> "com.google.apphosting.datastore.LocalDatastoreService"
+ * ```
+ */
+ private final Multimap
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.dreamlu.mica.auto.service;
+
+import com.google.auto.service.AutoService;
+import com.google.devtools.ksp.processing.SymbolProcessor;
+import com.google.devtools.ksp.processing.SymbolProcessorEnvironment;
+import com.google.devtools.ksp.processing.SymbolProcessorProvider;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * AutoService SymbolProcessorProvider
+ *
+ * @author L.cm
+ */
+@AutoService(SymbolProcessorProvider.class)
+public class AutoServiceSymbolProcessorProvider implements SymbolProcessorProvider {
+
+ @NotNull
+ @Override
+ public SymbolProcessor create(@NotNull SymbolProcessorEnvironment environment) {
+ return new AutoServiceSymbolProcessor(environment);
+ }
+
+}
diff --git a/src/test/java/net/dreamlu/mica/auto/service/AutoServiceSymbolProcessorTest.java b/src/test/java/net/dreamlu/mica/auto/service/AutoServiceSymbolProcessorTest.java
new file mode 100644
index 0000000..d9d2a0d
--- /dev/null
+++ b/src/test/java/net/dreamlu/mica/auto/service/AutoServiceSymbolProcessorTest.java
@@ -0,0 +1,112 @@
+package net.dreamlu.mica.auto.service;
+
+import com.tschuchort.compiletesting.CompilationResult;
+import com.tschuchort.compiletesting.KotlinCompilation;
+import com.tschuchort.compiletesting.KotlinCompilation.ExitCode;
+import com.tschuchort.compiletesting.KspKt;
+import com.tschuchort.compiletesting.SourceFile;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+
+import static com.google.common.truth.Truth.assertThat;
+
+@RunWith(Parameterized.class)
+public class AutoServiceSymbolProcessorTest {
+ private final boolean incremental;
+
+ public AutoServiceSymbolProcessorTest(boolean incremental) {
+ this.incremental = incremental;
+ }
+
+ @Parameters(name = "incremental={0}")
+ public static Collection