@Override public boolean handle( AnnotationValues<Synchronized> annotation, JCAnnotation ast, Node annotationNode) { Node methodNode = annotationNode.up(); if (methodNode == null || methodNode.getKind() != Kind.METHOD || !(methodNode.get() instanceof JCMethodDecl)) { annotationNode.addError("@Synchronized is legal only on methods."); return true; } JCMethodDecl method = (JCMethodDecl) methodNode.get(); if ((method.mods.flags & Flags.ABSTRACT) != 0) { annotationNode.addError("@Synchronized is legal only on concrete methods."); return true; } boolean isStatic = (method.mods.flags & Flags.STATIC) != 0; String lockName = annotation.getInstance().value(); boolean autoMake = false; if (lockName.length() == 0) { autoMake = true; lockName = isStatic ? STATIC_LOCK_NAME : INSTANCE_LOCK_NAME; } TreeMaker maker = methodNode.getTreeMaker(); if (fieldExists(lockName, methodNode) == MemberExistsResult.NOT_EXISTS) { if (!autoMake) { annotationNode.addError("The field " + new String(lockName) + " does not exist."); return true; } JCExpression objectType = chainDots(maker, methodNode, "java", "lang", "Object"); // We use 'new Object[0];' because quite unlike 'new Object();', empty arrays *ARE* // serializable! JCNewArray newObjectArray = maker.NewArray( chainDots(maker, methodNode, "java", "lang", "Object"), List.<JCExpression>of(maker.Literal(TypeTags.INT, 0)), null); JCVariableDecl fieldDecl = maker.VarDef( maker.Modifiers(Flags.FINAL | (isStatic ? Flags.STATIC : 0)), methodNode.toName(lockName), objectType, newObjectArray); injectField(methodNode.up(), fieldDecl); } if (method.body == null) return false; JCExpression lockNode = maker.Ident(methodNode.toName(lockName)); method.body = maker.Block(0, List.<JCStatement>of(maker.Synchronized(lockNode, method.body))); methodNode.rebuild(); return true; }
private JCStatement buildTryCatchBlock( JavacNode node, List<JCStatement> contents, String exception) { TreeMaker maker = node.getTreeMaker(); JCBlock tryBlock = maker.Block(0, contents); JCExpression varType = chainDots(maker, node, exception.split("\\.")); JCVariableDecl catchParam = maker.VarDef(maker.Modifiers(Flags.FINAL), node.toName("$ex"), varType, null); JCExpression lombokLombokSneakyThrowNameRef = chainDots(maker, node, "lombok", "Lombok", "sneakyThrow"); JCBlock catchBody = maker.Block( 0, List.<JCStatement>of( maker.Throw( maker.Apply( List.<JCExpression>nil(), lombokLombokSneakyThrowNameRef, List.<JCExpression>of(maker.Ident(node.toName("$ex"))))))); return maker.Try(tryBlock, List.of(maker.Catch(catchParam, catchBody)), null); }