[英]Create custom annotation for Lombok 1.16.8
我正在編寫一個名為 @PrintedValue 的自定義 Lombok 注釋,它生成方法打印 Hiii。 為此,我創建了如下注釋 class :
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.SOURCE)
public @interface PrintValue {
}
然后,我創建了兩個處理程序(javac 和 eclipse 處理程序)。 這是我的代碼:
@ProviderFor(EclipseAnnotationHandler.class) public class HandlePrintValue extends EclipseAnnotationHandler<PrintValue> {
@Override public void handle(AnnotationValues<PrintValue> annotation, Annotation ast, EclipseNode annotationNode) {
handleFlagUsage(annotationNode, ConfigurationKeys.PRINT_VALUE_FLAG_USAGE, "@PrintValue");
EclipseHandlerUtil.unboxAndRemoveAnnotationParameter(ast, "onType", "@PrintValue(onType=", annotationNode);
EclipseNode typeNode = annotationNode.up();
MethodDeclaration printValMethod = createPrintVal(typeNode, annotationNode, annotationNode.get(), ast);
injectMethod(typeNode, printValMethod);
return;
}
private MethodDeclaration createPrintVal(EclipseNode typeNode, EclipseNode errorNode, ASTNode astNode, Annotation source) {
TypeDeclaration typeDecl = (TypeDeclaration) typeNode.get();
MethodDeclaration method = new MethodDeclaration(typeDecl.compilationResult);
setGeneratedBy(method, astNode);
method.annotations = null;
method.modifiers = toEclipseModifier(AccessLevel.PUBLIC);
method.typeParameters = null;
method.returnType = TypeReference.baseTypeReference(TypeIds.T_void, 0);
method.selector = "printVal".toCharArray();
method.arguments = null;
method.binding = null;
method.thrownExceptions = null;
method.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
NameReference systemOutReference = createNameReference("System.out", source);
Expression[] printlnArguments = new Expression[] {new StringLiteral("Hiiii".toCharArray(), astNode.sourceStart, astNode.sourceEnd, 0)};
MessageSend printlnInvocation = new MessageSend();
printlnInvocation.arguments = printlnArguments;
printlnInvocation.receiver = systemOutReference;
printlnInvocation.selector = "println".toCharArray();
setGeneratedBy(printlnInvocation, source);
method.bodyStart = method.declarationSourceStart = method.sourceStart = astNode.sourceStart;
method.bodyEnd = method.declarationSourceEnd = method.sourceEnd = astNode.sourceEnd;
method.statements = new Statement[] {printlnInvocation};
return method;
}
}
@ProviderFor(JavacAnnotationHandler.class)
public class HandlePrintValue extends JavacAnnotationHandler<PrintValue> {
@Override
public void handle(AnnotationValues<PrintValue> annotation, JCAnnotation ast, JavacNode annotationNode) {
// JavacHandlerUtil.markAnnotationAsProcessed(annotationNode,
// HelloWorld.class);
handleFlagUsage(annotationNode, ConfigurationKeys.PRINT_VALUE_FLAG_USAGE, "@PrintValue");
Context context = annotationNode.getContext();
Javac8BasedLombokOptions options = Javac8BasedLombokOptions.replaceWithDelombokOptions(context);
options.deleteLombokAnnotations();
JavacHandlerUtil.deleteAnnotationIfNeccessary(annotationNode, PrintValue.class);
JavacHandlerUtil.deleteImportFromCompilationUnit(annotationNode, "lombok.AccessLevel");
JavacNode typeNode = annotationNode.up();
JCMethodDecl printValMethod = createPrintVal(typeNode);
JavacHandlerUtil.injectMethod(typeNode, printValMethod);
return;
}
private JCMethodDecl createPrintVal(JavacNode type) {
JavacTreeMaker treeMaker = type.getTreeMaker();
JCModifiers modifiers = treeMaker.Modifiers(Flags.PUBLIC);
List<JCTypeParameter> methodGenericTypes = List.<JCTypeParameter>nil();
JCExpression methodType = treeMaker.Type(Javac.createVoidType(treeMaker, CTC_VOID));
Name methodName = type.toName("printVal");
List<JCVariableDecl> methodParameters = List.<JCVariableDecl>nil();
List<JCExpression> methodThrows = List.<JCExpression>nil();
JCExpression printlnMethod = JavacHandlerUtil.chainDots(type, "System", "out", "println");
List<JCExpression> printlnArgs = List.<JCExpression>of(treeMaker.Literal("val"));
JCMethodInvocation printlnInvocation = treeMaker.Apply(List.<JCExpression>nil(), printlnMethod, printlnArgs);
JCBlock methodBody = treeMaker.Block(0, List.<JCStatement>of(treeMaker.Exec(printlnInvocation)));
JCExpression defaultValue = null;
return treeMaker.MethodDef(modifiers, methodName, methodType, methodGenericTypes, methodParameters, methodThrows, methodBody, defaultValue);
}
}
在構建我的項目並將生成的 lombok jar 添加到我的項目后,我可以調用 @PrintValue 注釋,但對於學生 class 未定義 printVal 方法。 導入 lombok.PrintValue;
public @PrintValue class Student {
private int age;
private String name;
}
我嘗試啟用注釋處理,但仍然遇到同樣的問題。 如果有人可以幫助我,我將不勝感激。
jdk :8 eclipse 2018-09龍目島1.16.8
添加新的 lombok 注釋的唯一方法是 fork lombok,並且您的注釋類型名 ( @PrintValue
)和處理程序位於以“lombok.”開頭的 package 中。 其原因很難用簡潔的答案來解釋:它是以下各項的組合:
當我說“fork lombok”時,我的意思是:
.SCL.lombok
and not .class
. 到目前為止,最簡單的方法是獲取 lombok 源(克隆 git 存儲庫),並在 lombok 擁有它們的同一位置創建您的注釋類型( /src/core/lombok/PrintValue.java
),以及在 lombok 擁有它們的相同位置創建您的處理程序(例如/src/core/lombok/eclipse/handlers/HandlePrintValue.java
)。
然后只需ant dist
然后java -jar dist/lombok.jar install /path/to/your/eclipse
。
如果您想為這些創建自己的 lombok 子包,請搜索lombok.extern
和 lombok lombok/extern
- 特別是在構建文件中(在buildScripts
子目錄中); 如果您希望注釋的全名是例如lombok.houria.PrintValue
,您需要告訴 lombok 的構建過程lombok.houria
不能得到.SCL.lombok
處理,就像lombok.extern
、 lombok
和lombok.experimental
don不。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.