@Override public void handle(AnnotationValues<Singleton> annotation, JCTree.JCAnnotation ast, JavacNode annotationNode) { Context context = annotationNode.getContext(); Javac8BasedLombokOptions options = Javac8BasedLombokOptions.replaceWithDelombokOptions(context); options.deleteLombokAnnotations(); //remove annotation deleteAnnotationIfNeccessary(annotationNode, Singleton.class); //remove import deleteImportFromCompilationUnit(annotationNode, "lombok.AccessLevel"); //private constructor JavacNode singletonClass = annotationNode.up(); JavacTreeMaker singletonClassTreeMaker = singletonClass.getTreeMaker(); addPrivateConstructor(singletonClass, singletonClassTreeMaker); //singleton holder JavacNode holderInnerClass = addInnerClass(singletonClass, singletonClassTreeMaker); //inject static field to this addInstanceVar(singletonClass, singletonClassTreeMaker, holderInnerClass); //add factory method addFactoryMethod(singletonClass, singletonClassTreeMaker, holderInnerClass); }
private void addInstanceVar(JavacNode singletonClass, JavacTreeMaker singletonClassTM, JavacNode holderClass) { JCTree.JCModifiers fieldMod = singletonClassTM.Modifiers(Flags.PRIVATE | Flags.STATIC | Flags.FINAL); JCTree.JCClassDecl singletonClassDecl = (JCTree.JCClassDecl) singletonClass.get(); JCTree.JCIdent singletonClassType = singletonClassTM.Ident(singletonClassDecl.name); JCTree.JCNewClass newKeyword = singletonClassTM.NewClass(null, List.nil(), singletonClassType, List.nil(), null); JCTree.JCVariableDecl instanceVar = singletonClassTM.VarDef(fieldMod, singletonClass.toName("INSTANCE"), singletonClassType, newKeyword); JavacHandlerUtil.injectField(holderClass, instanceVar); }
private void addPrivateConstructor(JavacNode singletonClass, JavacTreeMaker singletonTM) { JCTree.JCModifiers modifiers = singletonTM.Modifiers(Flags.PRIVATE); JCTree.JCBlock block = singletonTM.Block(0L, List.nil()); JCTree.JCMethodDecl constructor = singletonTM.MethodDef(modifiers, singletonClass.toName("<init>"), null, List.nil(), List.nil(), List.nil(), block, null); JavacHandlerUtil.injectMethod(singletonClass, constructor); }
public static <T extends Annotation> void addMethodCallInMethodBody(AnnotationValues<T> annotation, JCTree.JCAnnotation ast, JavacNode annotationNode, String methodWhereToAddName, java.util.List<String> methodToAddName, boolean addInFirstPosition) { JavacTreeMaker treeMaker = annotationNode.getTreeMaker(); JavacNode owner = annotationNode.up(); // the field where the @Annotation applies switch (owner.get().getClass().getSimpleName()) { case "JCClassDecl": JCClassDecl classDecl = (JCClassDecl) owner.get(); for (JCTree e : classDecl.defs) { if ("METHOD".equals(e.getKind().toString())) { JCMethodDecl md = (JCMethodDecl) e; if (methodWhereToAddName.equals(md.name.toString())) { JCExpression callIt=JavacHandlerUtil.chainDots(owner, methodToAddName.toArray(new String[0])); JCMethodInvocation factoryMethodCall=treeMaker.Apply(NIL_EXPRESSION, callIt, NIL_EXPRESSION); JCExpressionStatement exec = treeMaker.Exec(factoryMethodCall); if (addInFirstPosition) { md.body.stats = md.body.stats.prepend(exec); } else { md.body.stats = md.body.stats.append(exec); } } } } break; default: break; } owner.getAst().setChanged(); }
private JavacNode addInnerClass(JavacNode singletonClass, JavacTreeMaker singletonTM) { JCTree.JCModifiers modifiers = singletonTM.Modifiers(Flags.PRIVATE | Flags.STATIC); String innerClassName = singletonClass.getName() + "Holder"; JCTree.JCClassDecl innerClassDecl = singletonTM.ClassDef(modifiers, singletonClass.toName(innerClassName), List.nil(), null, List.nil(), List.nil()); return JavacHandlerUtil.injectType(singletonClass, innerClassDecl); }
JCExpression mavenParameterAnnotationType = chainDots(owner, annotationToAdd.toArray(new String[0]));
private void addFactoryMethod(JavacNode singletonClass, JavacTreeMaker singletonClassTreeMaker, JavacNode holderInnerClass) { JCTree.JCModifiers modifiers = singletonClassTreeMaker.Modifiers(Flags.PUBLIC | Flags.STATIC); JCTree.JCClassDecl singletonClassDecl = (JCTree.JCClassDecl) singletonClass.get(); JCTree.JCIdent singletonClassType = singletonClassTreeMaker.Ident(singletonClassDecl.name); JCTree.JCBlock block = addReturnBlock(singletonClassTreeMaker, holderInnerClass); JCTree.JCMethodDecl factoryMethod = singletonClassTreeMaker.MethodDef(modifiers, singletonClass.toName("getInstance"), singletonClassType, List.nil(), List.nil(), List.nil(), block, null); JavacHandlerUtil.injectMethod(singletonClass, factoryMethod); }