diff options
Diffstat (limited to 'src/lombok/javac/handlers')
-rw-r--r-- | src/lombok/javac/handlers/HandleData.java | 48 | ||||
-rw-r--r-- | src/lombok/javac/handlers/HandleGetter.java | 9 | ||||
-rw-r--r-- | src/lombok/javac/handlers/HandleSetter.java | 10 | ||||
-rw-r--r-- | src/lombok/javac/handlers/PKG.java | 36 |
4 files changed, 81 insertions, 22 deletions
diff --git a/src/lombok/javac/handlers/HandleData.java b/src/lombok/javac/handlers/HandleData.java index 48eb7f76..5d1cc913 100644 --- a/src/lombok/javac/handlers/HandleData.java +++ b/src/lombok/javac/handlers/HandleData.java @@ -1,7 +1,8 @@ package lombok.javac.handlers; -import java.util.ArrayList; -import java.util.List; +import java.lang.reflect.Modifier; + +import static lombok.javac.handlers.PKG.*; import lombok.Data; import lombok.core.AnnotationValues; @@ -12,9 +13,17 @@ import lombok.javac.JavacAST.Node; import org.mangosdk.spi.ProviderFor; import com.sun.tools.javac.code.Flags; +import com.sun.tools.javac.tree.TreeMaker; import com.sun.tools.javac.tree.JCTree.JCAnnotation; +import com.sun.tools.javac.tree.JCTree.JCAssign; import com.sun.tools.javac.tree.JCTree.JCClassDecl; +import com.sun.tools.javac.tree.JCTree.JCExpression; +import com.sun.tools.javac.tree.JCTree.JCFieldAccess; +import com.sun.tools.javac.tree.JCTree.JCMethodDecl; +import com.sun.tools.javac.tree.JCTree.JCModifiers; +import com.sun.tools.javac.tree.JCTree.JCStatement; import com.sun.tools.javac.tree.JCTree.JCVariableDecl; +import com.sun.tools.javac.util.List; @ProviderFor(JavacAnnotationHandler.class) public class HandleData implements JavacAnnotationHandler<Data> { @@ -25,25 +34,52 @@ public class HandleData implements JavacAnnotationHandler<Data> { long flags = typeDecl.mods.flags; boolean notAClass = (flags & (Flags.INTERFACE | Flags.ENUM | Flags.ANNOTATION)) != 0; - if ( typeDecl != null || notAClass ) { + if ( typeDecl == null || notAClass ) { annotationNode.addError("@Data is only supported on a class."); return false; } - List<Node> nodesForEquality = new ArrayList<Node>(); + List<Node> nodesForEquality = List.nil(); + List<Node> nodesForConstructorAndToString = List.nil(); for ( Node child : typeNode.down() ) { if ( child.getKind() != Kind.FIELD ) continue; JCVariableDecl fieldDecl = (JCVariableDecl) child.get(); long fieldFlags = fieldDecl.mods.flags; //Skip static fields. if ( (fieldFlags & Flags.STATIC) != 0 ) continue; - if ( (fieldFlags & Flags.TRANSIENT) == 0 ) nodesForEquality.add(child); + if ( (fieldFlags & Flags.TRANSIENT) == 0 ) nodesForEquality = nodesForEquality.append(child); + nodesForConstructorAndToString = nodesForConstructorAndToString.append(child); new HandleGetter().generateGetterForField(child, annotationNode.get()); if ( (fieldFlags & Flags.FINAL) == 0 ) new HandleSetter().generateSetterForField(child, annotationNode.get()); } - //TODO generate constructor, hashCode, equals, toString. + String staticConstructorName = annotation.getInstance().staticConstructor(); + JCMethodDecl constructor = createConstructor(staticConstructorName.equals(""), typeNode, nodesForConstructorAndToString); + injectMethod(typeNode, constructor); + + //TODO generate static constructors, hashCode, equals, toString. return true; } + + private JCMethodDecl createConstructor(boolean isPublic, Node typeNode, List<Node> fields) { + TreeMaker maker = typeNode.getTreeMaker(); + JCClassDecl type = (JCClassDecl) typeNode.get(); + + List<JCStatement> assigns = List.nil(); + List<JCVariableDecl> params = List.nil(); + + for ( Node fieldNode : fields ) { + JCVariableDecl field = (JCVariableDecl) fieldNode.get(); + JCVariableDecl param = maker.VarDef(maker.Modifiers(0), field.name, field.vartype, null); + params = params.append(param); + JCFieldAccess thisX = maker.Select(maker.Ident(fieldNode.toName("this")), field.name); + JCAssign assign = maker.Assign(thisX, maker.Ident(field.name)); + assigns = assigns.append(maker.Exec(assign)); + } + + JCModifiers mods = maker.Modifiers(isPublic ? Modifier.PUBLIC : Modifier.PRIVATE); + return maker.MethodDef(mods, + typeNode.toName("<init>"), null, type.typarams, params, List.<JCExpression>nil(), maker.Block(0L, assigns), null); + } } diff --git a/src/lombok/javac/handlers/HandleGetter.java b/src/lombok/javac/handlers/HandleGetter.java index 3405810b..f66247ff 100644 --- a/src/lombok/javac/handlers/HandleGetter.java +++ b/src/lombok/javac/handlers/HandleGetter.java @@ -1,7 +1,6 @@ package lombok.javac.handlers; import static lombok.javac.handlers.PKG.*; - import lombok.AccessLevel; import lombok.Getter; import lombok.core.AnnotationValues; @@ -16,7 +15,6 @@ import com.sun.tools.javac.code.Flags; import com.sun.tools.javac.tree.TreeMaker; import com.sun.tools.javac.tree.JCTree.JCAnnotation; import com.sun.tools.javac.tree.JCTree.JCBlock; -import com.sun.tools.javac.tree.JCTree.JCClassDecl; import com.sun.tools.javac.tree.JCTree.JCExpression; import com.sun.tools.javac.tree.JCTree.JCMethodDecl; import com.sun.tools.javac.tree.JCTree.JCStatement; @@ -75,14 +73,9 @@ public class HandleGetter implements JavacAnnotationHandler<Getter> { //continue with creating the getter } - JCClassDecl javacClassTree = (JCClassDecl) fieldNode.up().get(); - long access = toJavacModifier(level) | (fieldDecl.mods.flags & Flags.STATIC); - JCMethodDecl getterMethod = createGetter(access, fieldNode, fieldNode.getTreeMaker()); - javacClassTree.defs = javacClassTree.defs.append(getterMethod); - - fieldNode.up().add(getterMethod, Kind.METHOD).recursiveSetHandled(); + injectMethod(fieldNode.up(), createGetter(access, fieldNode, fieldNode.getTreeMaker())); return true; } diff --git a/src/lombok/javac/handlers/HandleSetter.java b/src/lombok/javac/handlers/HandleSetter.java index 4999b5d8..2b766db1 100644 --- a/src/lombok/javac/handlers/HandleSetter.java +++ b/src/lombok/javac/handlers/HandleSetter.java @@ -17,7 +17,6 @@ import com.sun.tools.javac.tree.TreeMaker; import com.sun.tools.javac.tree.JCTree.JCAnnotation; import com.sun.tools.javac.tree.JCTree.JCAssign; import com.sun.tools.javac.tree.JCTree.JCBlock; -import com.sun.tools.javac.tree.JCTree.JCClassDecl; import com.sun.tools.javac.tree.JCTree.JCExpression; import com.sun.tools.javac.tree.JCTree.JCFieldAccess; import com.sun.tools.javac.tree.JCTree.JCMethodDecl; @@ -78,14 +77,9 @@ public class HandleSetter implements JavacAnnotationHandler<Setter> { //continue with creating the setter } - JCClassDecl javacClassTree = (JCClassDecl) fieldNode.up().get(); - long access = toJavacModifier(level) | (fieldDecl.mods.flags & Flags.STATIC); - JCMethodDecl setterMethod = createSetter(access, fieldNode, fieldNode.getTreeMaker()); - javacClassTree.defs = javacClassTree.defs.append(setterMethod); - - fieldNode.up().add(setterMethod, Kind.METHOD).recursiveSetHandled(); + injectMethod(fieldNode.up(), createSetter(access, fieldNode, fieldNode.getTreeMaker())); return true; } @@ -98,7 +92,7 @@ public class HandleSetter implements JavacAnnotationHandler<Setter> { JCBlock methodBody = treeMaker.Block(0, List.<JCStatement>of(treeMaker.Exec(assign))); Name methodName = field.toName(toSetterName(fieldDecl)); - JCVariableDecl param = treeMaker.VarDef(treeMaker.Modifiers(0, List.<JCAnnotation>nil()), fieldDecl.name, fieldDecl.vartype, null); + JCVariableDecl param = treeMaker.VarDef(treeMaker.Modifiers(0), fieldDecl.name, fieldDecl.vartype, null); JCExpression methodType = treeMaker.Type(field.getSymbolTable().voidType); List<JCTypeParameter> methodGenericParams = List.nil(); diff --git a/src/lombok/javac/handlers/PKG.java b/src/lombok/javac/handlers/PKG.java index 138559a9..615e4c80 100644 --- a/src/lombok/javac/handlers/PKG.java +++ b/src/lombok/javac/handlers/PKG.java @@ -2,13 +2,16 @@ package lombok.javac.handlers; import java.lang.reflect.Modifier; +import com.sun.tools.javac.code.Flags; import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.JCTree.JCClassDecl; import com.sun.tools.javac.tree.JCTree.JCMethodDecl; import com.sun.tools.javac.tree.JCTree.JCVariableDecl; +import com.sun.tools.javac.util.List; import lombok.AccessLevel; import lombok.core.TransformationsUtil; +import lombok.core.AST.Kind; import lombok.javac.JavacAST; class PKG { @@ -66,4 +69,37 @@ class PKG { return Modifier.PROTECTED; } } + + static void injectMethod(JavacAST.Node typeNode, JCMethodDecl method) { + JCClassDecl type = (JCClassDecl) typeNode.get(); + + if ( method.getName().contentEquals("<init>") ) { + //Scan for default constructor, and remove it. + int idx = 0; + for ( JCTree def : type.defs ) { + if ( def instanceof JCMethodDecl ) { + if ( (((JCMethodDecl)def).mods.flags & Flags.GENERATEDCONSTR) != 0 ) { + JavacAST.Node tossMe = typeNode.getNodeFor(def); + if ( tossMe != null ) tossMe.up().removeChild(tossMe); + type.defs = addAllButOne(type.defs, idx); + break; + } + } + idx++; + } + } + + type.defs = type.defs.append(method); + + typeNode.add(method, Kind.METHOD).recursiveSetHandled(); + } + + private static List<JCTree> addAllButOne(List<JCTree> defs, int idx) { + List<JCTree> out = List.nil(); + int i = 0; + for ( JCTree def : defs ) { + if ( i++ != idx ) out = out.append(def); + } + return out; + } } |