From d30970ed6341193a9a9b1e228c521d4eb542bcf4 Mon Sep 17 00:00:00 2001 From: wangqi Date: Sat, 16 Nov 2024 21:07:46 +0800 Subject: [PATCH] feature: update annotation processor --- .../processor/CarpAnnotationProcessor.java | 22 +++---- .../processor/CarpProcessorPlugin.java | 6 +- .../plugins/AbstractClassGeneratePlugin.java | 23 ++++++- .../plugins/AbstractMethodGeneratePlugin.java | 26 -------- .../plugins/AbstractProcessorPlugin.java | 20 +++--- .../plugins/jackson/JacksonGetter.java | 33 ---------- .../javapoet/JacksonJavapoetPlugin.java | 56 ----------------- .../processor/plugins/web/HandlerWriter.java | 62 +++++++++---------- .../processor/plugins/web/WebPlugin.java | 5 +- .../processor/specs/GeneratedMethodSpecs.java | 47 ++++++++++++++ .../specs/GeneratedTryCatchSpecs.java | 30 +++++++++ .../ElementUtil.java} | 20 +++--- 12 files changed, 167 insertions(+), 183 deletions(-) delete mode 100644 carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/plugins/AbstractMethodGeneratePlugin.java delete mode 100644 carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/plugins/jackson/JacksonGetter.java delete mode 100644 carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/plugins/jackson/javapoet/JacksonJavapoetPlugin.java create mode 100644 carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/specs/GeneratedMethodSpecs.java create mode 100644 carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/specs/GeneratedTryCatchSpecs.java rename carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/{CarpProcessor.java => util/ElementUtil.java} (59%) diff --git a/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/CarpAnnotationProcessor.java b/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/CarpAnnotationProcessor.java index 978ea80..aab5baa 100644 --- a/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/CarpAnnotationProcessor.java +++ b/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/CarpAnnotationProcessor.java @@ -18,7 +18,6 @@ package cn.sliew.carp.support.annotation.processor; -import cn.sliew.carp.support.annotation.processor.plugins.jackson.javapoet.JacksonJavapoetPlugin; import cn.sliew.carp.support.annotation.processor.plugins.web.WebPlugin; import com.google.auto.common.BasicAnnotationProcessor; import com.google.auto.service.AutoService; @@ -26,44 +25,45 @@ import com.palantir.javapoet.JavaFile; import javax.annotation.processing.*; -import javax.lang.model.SourceVersion; import javax.lang.model.element.TypeElement; import javax.tools.Diagnostic; import java.io.IOException; import java.util.Collection; import java.util.List; import java.util.Set; +import java.util.stream.Collectors; /** + * 参考 lombok.core.AnnotationProcessor + * * @see BasicAnnotationProcessor */ -@SupportedAnnotationTypes({"cn.sliew.carp.support.annotation.processor.CarpProcessor"}) -@SupportedSourceVersion(SourceVersion.RELEASE_17) +@SupportedAnnotationTypes("*") @AutoService(Processor.class) public class CarpAnnotationProcessor extends AbstractProcessor { - private List plugins = Lists.newArrayList(); + private List registered = Lists.newArrayList(); + private List active = Lists.newArrayList(); @Override public synchronized void init(ProcessingEnvironment processingEnv) { super.init(processingEnv); - plugins.add(new WebPlugin()); - plugins.add(new JacksonJavapoetPlugin()); - plugins.forEach(plugin -> plugin.init(processingEnv)); + registered.add(new WebPlugin()); + active = registered.stream().filter(plugin -> plugin.support(processingEnv)).collect(Collectors.toList()); } @Override public boolean process(Set annotations, RoundEnvironment roundEnv) { try { - processInternal(roundEnv); + processInternal(annotations, roundEnv); } catch (Exception e) { processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "Exception occurred %s".formatted(e)); } return false; } - protected void processInternal(RoundEnvironment roundEnv) { - plugins.stream().map(plugin -> plugin.process(roundEnv.getElementsAnnotatedWith(plugin.supported()))) + protected void processInternal(Set annotations, RoundEnvironment roundEnv) { + active.stream().map(plugin -> plugin.process(roundEnv.getElementsAnnotatedWith(plugin.supported()), roundEnv)) .flatMap(Collection::stream) .forEach(this::writeFile); } diff --git a/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/CarpProcessorPlugin.java b/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/CarpProcessorPlugin.java index ff342d5..d37c32b 100644 --- a/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/CarpProcessorPlugin.java +++ b/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/CarpProcessorPlugin.java @@ -22,20 +22,22 @@ import com.palantir.javapoet.JavaFile; import javax.annotation.processing.ProcessingEnvironment; +import javax.annotation.processing.RoundEnvironment; import javax.lang.model.element.Element; import java.lang.annotation.Annotation; import java.util.Collection; import java.util.Set; /** + * 参考 lombok.core.AnnotationProcessor.ProcessorDescriptor * @see BasicAnnotationProcessor.Step */ public interface CarpProcessorPlugin { - void init(ProcessingEnvironment processingEnv); + boolean support(ProcessingEnvironment processingEnv); Class supported(); - Collection process(Set annotated); + Collection process(Set annotated, RoundEnvironment roundEnv); } diff --git a/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/plugins/AbstractClassGeneratePlugin.java b/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/plugins/AbstractClassGeneratePlugin.java index 89b6d7a..1324792 100644 --- a/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/plugins/AbstractClassGeneratePlugin.java +++ b/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/plugins/AbstractClassGeneratePlugin.java @@ -18,9 +18,30 @@ package cn.sliew.carp.support.annotation.processor.plugins; +import cn.sliew.carp.support.annotation.processor.util.ProcessingEnvUtils; +import com.palantir.javapoet.JavaFile; +import com.palantir.javapoet.TypeSpec; + +import javax.lang.model.element.ExecutableElement; + /** - * 生成一个新的类,实现特定接口 + * 生成一个新的类,实现特定接口。 + * Annotation Processor 只能实现编译时获取特定的注解标记的类, + * 获取到之后生成新的类和修改已有的类已经超出了 Annotation Processor 的功能。 + * 当需要新生成类时可以使用 javapoet 等工具,生成新的 .java 文件 + * 修改已有的类则需要使用 javac,这是 java 的内部类。目前没有相关的库可以辅助生成, + * 做的比较好的也就是 lombok。参考:https://stackoverflow.com/a/70008734 */ public abstract class AbstractClassGeneratePlugin extends AbstractProcessorPlugin { + @Override + protected JavaFile getJavaFile(ElementMethod elementMethod, IndexedValue indexedValue) { + var annotedMethod = indexedValue.value(); + var typeSpec = createType(elementMethod, indexedValue, annotedMethod); + String packageName = ProcessingEnvUtils.getPackageName(processingEnv, annotedMethod); + return JavaFile.builder(packageName, typeSpec).build(); + } + + protected abstract TypeSpec createType(ElementMethod elementMethod, IndexedValue indexedValue, ExecutableElement handlerMethod); + } diff --git a/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/plugins/AbstractMethodGeneratePlugin.java b/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/plugins/AbstractMethodGeneratePlugin.java deleted file mode 100644 index 955730e..0000000 --- a/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/plugins/AbstractMethodGeneratePlugin.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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 cn.sliew.carp.support.annotation.processor.plugins; - -/** - * 在原类中生成一个新方法 - */ -public abstract class AbstractMethodGeneratePlugin extends AbstractProcessorPlugin { - -} diff --git a/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/plugins/AbstractProcessorPlugin.java b/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/plugins/AbstractProcessorPlugin.java index 595ed82..0edf87c 100644 --- a/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/plugins/AbstractProcessorPlugin.java +++ b/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/plugins/AbstractProcessorPlugin.java @@ -19,11 +19,10 @@ package cn.sliew.carp.support.annotation.processor.plugins; import cn.sliew.carp.support.annotation.processor.CarpProcessorPlugin; -import cn.sliew.carp.support.annotation.processor.util.ProcessingEnvUtils; import com.palantir.javapoet.JavaFile; -import com.palantir.javapoet.TypeSpec; import javax.annotation.processing.ProcessingEnvironment; +import javax.annotation.processing.RoundEnvironment; import javax.lang.model.element.AnnotationMirror; import javax.lang.model.element.Element; import javax.lang.model.element.ExecutableElement; @@ -31,6 +30,7 @@ import javax.tools.Diagnostic; import java.io.PrintWriter; import java.io.StringWriter; +import java.lang.annotation.Annotation; import java.util.Collection; import java.util.List; import java.util.Map; @@ -46,12 +46,15 @@ public abstract class AbstractProcessorPlugin implements CarpProcessorPlugin { protected ProcessingEnvironment processingEnv; @Override - public void init(ProcessingEnvironment processingEnv) { + public boolean support(ProcessingEnvironment processingEnv) { this.processingEnv = processingEnv; + return false; } + public abstract Class supported(); + @Override - public Collection process(Set annotated) { + public Collection process(Set annotated, RoundEnvironment roundEnv) { Map> nameDataListMap = ElementFilter .methodsIn(annotated) .stream() @@ -80,14 +83,7 @@ private JavaFile handle(ElementMethod elementMethod, IndexedValue indexedValue) { - var handlerMethod = indexedValue.value(); - var typeSpec = createType(elementMethod, indexedValue, handlerMethod); - String packageName = ProcessingEnvUtils.getPackageName(processingEnv, handlerMethod); - return JavaFile.builder(packageName, typeSpec).build(); - } - - protected abstract TypeSpec createType(ElementMethod elementMethod, IndexedValue indexedValue, ExecutableElement handlerMethod); + protected abstract JavaFile getJavaFile(ElementMethod elementMethod, IndexedValue indexedValue); protected void log(String msg) { if (processingEnv.getOptions().containsKey("debug")) { diff --git a/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/plugins/jackson/JacksonGetter.java b/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/plugins/jackson/JacksonGetter.java deleted file mode 100644 index 30cce67..0000000 --- a/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/plugins/jackson/JacksonGetter.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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 cn.sliew.carp.support.annotation.processor.plugins.jackson; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Retention(RetentionPolicy.SOURCE) -@Target(ElementType.METHOD) -public @interface JacksonGetter { - - Class mapping(); - - String attribute(); -} diff --git a/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/plugins/jackson/javapoet/JacksonJavapoetPlugin.java b/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/plugins/jackson/javapoet/JacksonJavapoetPlugin.java deleted file mode 100644 index f10981d..0000000 --- a/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/plugins/jackson/javapoet/JacksonJavapoetPlugin.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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 cn.sliew.carp.support.annotation.processor.plugins.jackson.javapoet; - -import cn.sliew.carp.support.annotation.processor.plugins.AbstractMethodGeneratePlugin; -import cn.sliew.carp.support.annotation.processor.plugins.IndexedValue; -import cn.sliew.carp.support.annotation.processor.plugins.ElementMethod; -import cn.sliew.carp.support.annotation.processor.plugins.jackson.JacksonGetter; -import com.palantir.javapoet.JavaFile; -import com.palantir.javapoet.TypeSpec; - -import javax.annotation.processing.ProcessingEnvironment; -import javax.lang.model.element.Element; -import javax.lang.model.element.ExecutableElement; -import java.lang.annotation.Annotation; -import java.util.Collection; -import java.util.Set; - -public class JacksonJavapoetPlugin extends AbstractMethodGeneratePlugin { - - @Override - public void init(ProcessingEnvironment processingEnv) { - super.init(processingEnv); - } - - @Override - public Class supported() { - return JacksonGetter.class; - } - - @Override - public Collection process(Set annotated) { - return null; - } - - @Override - protected TypeSpec createType(ElementMethod nameData, IndexedValue indexedValue, ExecutableElement handlerMethod) { - return null; - } -} diff --git a/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/plugins/web/HandlerWriter.java b/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/plugins/web/HandlerWriter.java index a36094d..339b671 100644 --- a/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/plugins/web/HandlerWriter.java +++ b/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/plugins/web/HandlerWriter.java @@ -18,19 +18,24 @@ package cn.sliew.carp.support.annotation.processor.plugins.web; +import cn.sliew.carp.support.annotation.processor.specs.GeneratedMethodSpecs; +import cn.sliew.carp.support.annotation.processor.util.ElementUtil; import com.palantir.javapoet.*; import javax.annotation.processing.ProcessingEnvironment; -import javax.lang.model.element.*; +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.Modifier; +import javax.lang.model.element.VariableElement; import javax.lang.model.type.TypeKind; import javax.lang.model.type.TypeMirror; -import javax.lang.model.util.ElementFilter; import javax.lang.model.util.Types; import java.util.List; import java.util.Objects; class HandlerWriter { + private static final String CONTROLLER = "controller"; + private ExecutableElement httpMethodElement; private ExecutableElement produceElement; private ExecutableElement processElement; @@ -42,10 +47,10 @@ class HandlerWriter { this.typeUtils = processingEnv.getTypeUtils(); var handlerInterfaceElement = processingEnv.getElementUtils().getTypeElement(RequestHandler.class.getCanonicalName()); if (Objects.nonNull(handlerInterfaceElement)) { - this.httpMethodElement = getMethodElement(handlerInterfaceElement, "method"); - this.produceElement = getMethodElement(handlerInterfaceElement, "produce"); - this.processElement = getMethodElement(handlerInterfaceElement, "process"); - this.pathElement = getMethodElement(handlerInterfaceElement, "path"); + this.httpMethodElement = ElementUtil.getMethodElement(handlerInterfaceElement, "method"); + this.produceElement = ElementUtil.getMethodElement(handlerInterfaceElement, "produce"); + this.processElement = ElementUtil.getMethodElement(handlerInterfaceElement, "process"); + this.pathElement = ElementUtil.getMethodElement(handlerInterfaceElement, "path"); this.requestType = processingEnv.getElementUtils() .getTypeElement(Request.class.getCanonicalName()) .asType(); @@ -54,21 +59,14 @@ class HandlerWriter { private static MethodSpec constructor(TypeName typeName) { return MethodSpec.constructorBuilder() - .addParameter(ParameterSpec.builder(typeName, "controller").build()) - .addCode("this.controller = controller;") + .addParameter(ParameterSpec.builder(typeName, CONTROLLER).build()) + .addCode("this.%s = %s;".formatted(CONTROLLER, CONTROLLER)) .build(); } - private static ExecutableElement getMethodElement(TypeElement typeElement, String elementName) { - return ElementFilter.methodsIn(typeElement.getEnclosedElements()).stream() - .filter(it -> it.getSimpleName().toString().equals(elementName)) - .findFirst() - .get(); - } - TypeSpec buildHandler(String handlerMethodName, ExecutableElement handler, TypeName typeName, RequestHandle annotation) { return TypeSpec.classBuilder(handlerMethodName) - .addField(FieldSpec.builder(typeName, "controller", Modifier.FINAL, Modifier.PRIVATE).build()) + .addField(FieldSpec.builder(typeName, CONTROLLER, Modifier.FINAL, Modifier.PRIVATE).build()) .addMethod(constructor(typeName)) // .addAnnotation(Generated.class) .addSuperinterface(TypeName.get(RequestHandler.class)) @@ -83,21 +81,27 @@ TypeSpec buildHandler(String handlerMethodName, ExecutableElement handler, TypeN } private MethodSpec method(HttpMethod httpMethod) { - return MethodSpec.overriding(httpMethodElement) - .addCode("return $T.$L;", httpMethod.getClass(), httpMethod.toString()) - .build(); + return GeneratedMethodSpecs.generatedOverrideMethodSpec(httpMethodElement, + CodeBlock.builder() + .add("return $T.$L;", httpMethod.getClass(), httpMethod.toString()) + .build() + ); } private MethodSpec path(String value) { - return MethodSpec.overriding(pathElement) - .addCode("return $S;", value) - .build(); + return GeneratedMethodSpecs.generatedOverrideMethodSpec(pathElement, + CodeBlock.builder() + .add("return $S;", value) + .build() + ); } private MethodSpec produce(String produce) { - return MethodSpec.overriding(produceElement) - .addCode("return $S;", produce) - .build(); + return GeneratedMethodSpecs.generatedOverrideMethodSpec(produceElement, + CodeBlock.builder() + .add("return $S;", produce) + .build() + ); } private MethodSpec process(ExecutableElement handlerMethod) { @@ -125,13 +129,7 @@ private CodeBlock controllerCall(ExecutableElement handlerMethod, List 1 || !doesParamTypesMatchRequest(parameters)) { throw new RuntimeException("Too many parameters or type of param is not Request"); } - var methodCallParams = parameters.stream().map(VariableElement::getSimpleName).map(Name::toString) - .findFirst() - .map(__ -> "(arg0)") - .orElse("()"); - return CodeBlock.builder() - .add("controller.$L$L", handlerMethod.getSimpleName().toString(), methodCallParams) - .build(); + return GeneratedMethodSpecs.generatedMethodCallSpec(parameters, CONTROLLER, handlerMethod); } private boolean doesParamTypesMatchRequest(List parameters) { diff --git a/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/plugins/web/WebPlugin.java b/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/plugins/web/WebPlugin.java index 50cb7ae..7519866 100644 --- a/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/plugins/web/WebPlugin.java +++ b/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/plugins/web/WebPlugin.java @@ -33,9 +33,10 @@ public class WebPlugin extends AbstractClassGeneratePlugin { private HandlerWriter handlerWriter; @Override - public void init(ProcessingEnvironment processingEnv) { - super.init(processingEnv); + public boolean support(ProcessingEnvironment processingEnv) { + super.support(processingEnv); this.handlerWriter = new HandlerWriter(processingEnv); + return false; } @Override diff --git a/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/specs/GeneratedMethodSpecs.java b/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/specs/GeneratedMethodSpecs.java new file mode 100644 index 0000000..596abde --- /dev/null +++ b/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/specs/GeneratedMethodSpecs.java @@ -0,0 +1,47 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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 cn.sliew.carp.support.annotation.processor.specs; + +import com.palantir.javapoet.CodeBlock; +import com.palantir.javapoet.MethodSpec; + +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.Name; +import javax.lang.model.element.VariableElement; +import java.util.List; + +public enum GeneratedMethodSpecs { + ; + + public static MethodSpec generatedOverrideMethodSpec(ExecutableElement overrideMethod, CodeBlock methodBody) { + return MethodSpec.overriding(overrideMethod) + .addCode(methodBody) + .build(); + } + + public static CodeBlock generatedMethodCallSpec(List parameters, String callObject, ExecutableElement callMethod) { + var methodCallParams = parameters.stream().map(VariableElement::getSimpleName).map(Name::toString) + .findFirst() + .map(__ -> "(arg0)") + .orElse("()"); + return CodeBlock.builder() + .add(callObject + ".$L$L", callMethod.getSimpleName().toString(), methodCallParams) + .build(); + } +} diff --git a/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/specs/GeneratedTryCatchSpecs.java b/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/specs/GeneratedTryCatchSpecs.java new file mode 100644 index 0000000..87e89ef --- /dev/null +++ b/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/specs/GeneratedTryCatchSpecs.java @@ -0,0 +1,30 @@ +package cn.sliew.carp.support.annotation.processor.specs; + +import com.palantir.javapoet.CodeBlock; + +public enum GeneratedTryCatchSpecs { + ; + + public static CodeBlock tryClause(CodeBlock methodCall, CodeBlock catchClause) { + return CodeBlock.builder() + .beginControlFlow("try") + .add(methodCall) + .endControlFlow() + .add(catchClause) + .build(); + } + + public static CodeBlock catchClause(CodeBlock exceptionCall) { + return CodeBlock.builder() + .beginControlFlow("catch ($T e)", Exception.class) + .beginControlFlow("try") + .addStatement(exceptionCall) + .endControlFlow() + .beginControlFlow("catch ($T innerException)", Exception.class) + .addStatement("throw new $T(innerException)", RuntimeException.class) + .endControlFlow() + .addStatement("throw new $T(e)", RuntimeException.class) + .endControlFlow() + .build(); + } +} diff --git a/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/CarpProcessor.java b/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/util/ElementUtil.java similarity index 59% rename from carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/CarpProcessor.java rename to carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/util/ElementUtil.java index fc5ee53..4346fd2 100644 --- a/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/CarpProcessor.java +++ b/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/util/ElementUtil.java @@ -16,15 +16,19 @@ * limitations under the License. */ -package cn.sliew.carp.support.annotation.processor; +package cn.sliew.carp.support.annotation.processor.util; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.TypeElement; +import javax.lang.model.util.ElementFilter; -@Target({ElementType.TYPE}) -@Retention(RetentionPolicy.SOURCE) -public @interface CarpProcessor { +public enum ElementUtil { + ; + public static ExecutableElement getMethodElement(TypeElement typeElement, String elementName) { + return ElementFilter.methodsIn(typeElement.getEnclosedElements()).stream() + .filter(it -> it.getSimpleName().toString().equals(elementName)) + .findFirst() + .get(); + } }