aboutsummaryrefslogtreecommitdiff
path: root/src/lombok
diff options
context:
space:
mode:
Diffstat (limited to 'src/lombok')
-rw-r--r--src/lombok/eclipse/handlers/PKG.java4
-rw-r--r--src/lombok/javac/handlers/HandleData.java70
-rw-r--r--src/lombok/javac/handlers/PKG.java23
3 files changed, 89 insertions, 8 deletions
diff --git a/src/lombok/eclipse/handlers/PKG.java b/src/lombok/eclipse/handlers/PKG.java
index 3cfbf9c6..e9d12b62 100644
--- a/src/lombok/eclipse/handlers/PKG.java
+++ b/src/lombok/eclipse/handlers/PKG.java
@@ -50,7 +50,7 @@ class PKG {
node = node.up();
}
- if ( node.get() instanceof TypeDeclaration ) {
+ if ( node != null && node.get() instanceof TypeDeclaration ) {
TypeDeclaration typeDecl = (TypeDeclaration)node.get();
if ( typeDecl.methods != null ) for ( AbstractMethodDeclaration def : typeDecl.methods ) {
char[] mName = ((AbstractMethodDeclaration)def).selector;
@@ -71,7 +71,7 @@ class PKG {
node = node.up();
}
- if ( node.get() instanceof TypeDeclaration ) {
+ if ( node != null && node.get() instanceof TypeDeclaration ) {
TypeDeclaration typeDecl = (TypeDeclaration)node.get();
if ( typeDecl.methods != null ) for ( AbstractMethodDeclaration def : typeDecl.methods ) {
if ( def instanceof ConstructorDeclaration ) {
diff --git a/src/lombok/javac/handlers/HandleData.java b/src/lombok/javac/handlers/HandleData.java
index 5d1cc913..8ab50812 100644
--- a/src/lombok/javac/handlers/HandleData.java
+++ b/src/lombok/javac/handlers/HandleData.java
@@ -16,12 +16,17 @@ 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.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.JCIdent;
import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
import com.sun.tools.javac.tree.JCTree.JCModifiers;
+import com.sun.tools.javac.tree.JCTree.JCReturn;
import com.sun.tools.javac.tree.JCTree.JCStatement;
+import com.sun.tools.javac.tree.JCTree.JCTypeApply;
+import com.sun.tools.javac.tree.JCTree.JCTypeParameter;
import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
import com.sun.tools.javac.util.List;
@@ -55,10 +60,18 @@ public class HandleData implements JavacAnnotationHandler<Data> {
}
String staticConstructorName = annotation.getInstance().staticConstructor();
- JCMethodDecl constructor = createConstructor(staticConstructorName.equals(""), typeNode, nodesForConstructorAndToString);
- injectMethod(typeNode, constructor);
- //TODO generate static constructors, hashCode, equals, toString.
+ if ( constructorExists(typeNode) == MethodExistsResult.NOT_EXISTS ) {
+ JCMethodDecl constructor = createConstructor(staticConstructorName.equals(""), typeNode, nodesForConstructorAndToString);
+ injectMethod(typeNode, constructor);
+ }
+
+ if ( !staticConstructorName.isEmpty() && methodExists("of", typeNode) == MethodExistsResult.NOT_EXISTS ) {
+ JCMethodDecl staticConstructor = createStaticConstructor(staticConstructorName, typeNode, nodesForConstructorAndToString);
+ injectMethod(typeNode, staticConstructor);
+ }
+
+ //TODO hashCode, equals, toString.
return true;
}
@@ -79,7 +92,54 @@ public class HandleData implements JavacAnnotationHandler<Data> {
}
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);
+ return maker.MethodDef(mods, typeNode.toName("<init>"),
+ null, type.typarams, params, List.<JCExpression>nil(), maker.Block(0L, assigns), null);
+ }
+
+ private JCMethodDecl createStaticConstructor(String name, Node typeNode, List<Node> fields) {
+ TreeMaker maker = typeNode.getTreeMaker();
+ JCClassDecl type = (JCClassDecl) typeNode.get();
+
+ JCModifiers mods = maker.Modifiers(Flags.STATIC);
+
+ JCExpression returnType, constructorType;
+
+ List<JCTypeParameter> typeParams = List.nil();
+ List<JCVariableDecl> params = List.nil();
+ List<JCExpression> typeArgs1 = List.nil();
+ List<JCExpression> typeArgs2 = List.nil();
+ List<JCExpression> args = List.nil();
+
+ if ( !type.typarams.isEmpty() ) {
+ for ( JCTypeParameter param : type.typarams ) {
+ typeArgs1 = typeArgs1.append(maker.Ident(param.name));
+ typeArgs2 = typeArgs2.append(maker.Ident(param.name));
+ typeParams = typeParams.append(maker.TypeParameter(param.name, param.bounds));
+ }
+ returnType = maker.TypeApply(maker.Ident(type.name), typeArgs1);
+ constructorType = maker.TypeApply(maker.Ident(type.name), typeArgs2);
+ } else {
+ returnType = maker.Ident(type.name);
+ constructorType = maker.Ident(type.name);
+ }
+
+ for ( Node fieldNode : fields ) {
+ JCVariableDecl field = (JCVariableDecl) fieldNode.get();
+ JCExpression pType;
+ if ( field.vartype instanceof JCIdent ) pType = maker.Ident(((JCIdent)field.vartype).name);
+ else if ( field.vartype instanceof JCTypeApply ) {
+ JCTypeApply typeApply = (JCTypeApply) field.vartype;
+ List<JCExpression> tArgs = List.nil();
+ for ( JCExpression arg : typeApply.arguments ) tArgs = tArgs.append(arg);
+ pType = maker.TypeApply(typeApply.clazz, tArgs);
+ } else pType = field.vartype;
+ JCVariableDecl param = maker.VarDef(maker.Modifiers(0), field.name, pType, null);
+ params = params.append(param);
+ args = args.append(maker.Ident(field.name));
+ }
+ JCReturn returnStatement = maker.Return(maker.NewClass(null, List.<JCExpression>nil(), constructorType, args, null));
+ JCBlock body = maker.Block(0, List.<JCStatement>of(returnStatement));
+
+ return maker.MethodDef(mods, typeNode.toName(name), returnType, typeParams, params, List.<JCExpression>nil(), body, null);
}
}
diff --git a/src/lombok/javac/handlers/PKG.java b/src/lombok/javac/handlers/PKG.java
index 615e4c80..25d1a93e 100644
--- a/src/lombok/javac/handlers/PKG.java
+++ b/src/lombok/javac/handlers/PKG.java
@@ -40,7 +40,7 @@ class PKG {
node = node.up();
}
- if ( node.get() instanceof JCClassDecl ) {
+ if ( node != null && node.get() instanceof JCClassDecl ) {
for ( JCTree def : ((JCClassDecl)node.get()).defs ) {
if ( def instanceof JCMethodDecl ) {
if ( ((JCMethodDecl)def).name.contentEquals(methodName) ) {
@@ -55,6 +55,27 @@ class PKG {
return MethodExistsResult.NOT_EXISTS;
}
+ static MethodExistsResult constructorExists(JavacAST.Node node) {
+ while ( node != null && !(node.get() instanceof JCClassDecl) ) {
+ node = node.up();
+ }
+
+ if ( node != null && node.get() instanceof JCClassDecl ) {
+ for ( JCTree def : ((JCClassDecl)node.get()).defs ) {
+ if ( def instanceof JCMethodDecl ) {
+ if ( ((JCMethodDecl)def).name.contentEquals("<init>") ) {
+ if ( (((JCMethodDecl)def).mods.flags & Flags.GENERATEDCONSTR) != 0 ) continue;
+ JavacAST.Node existing = node.getNodeFor(def);
+ if ( existing == null || !existing.isHandled() ) return MethodExistsResult.EXISTS_BY_USER;
+ return MethodExistsResult.EXISTS_BY_LOMBOK;
+ }
+ }
+ }
+ }
+
+ return MethodExistsResult.NOT_EXISTS;
+ }
+
static int toJavacModifier(AccessLevel accessLevel) {
switch ( accessLevel ) {
case MODULE: