diff options
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/lombok/NoArgsConstructor.java | 11 | ||||
-rw-r--r-- | src/core/lombok/eclipse/handlers/HandleConstructor.java | 77 | ||||
-rw-r--r-- | src/core/lombok/eclipse/handlers/HandleData.java | 2 | ||||
-rw-r--r-- | src/core/lombok/javac/handlers/HandleConstructor.java | 50 | ||||
-rw-r--r-- | src/core/lombok/javac/handlers/HandleData.java | 2 |
5 files changed, 103 insertions, 39 deletions
diff --git a/src/core/lombok/NoArgsConstructor.java b/src/core/lombok/NoArgsConstructor.java index 392fef8b..4662cb5f 100644 --- a/src/core/lombok/NoArgsConstructor.java +++ b/src/core/lombok/NoArgsConstructor.java @@ -48,15 +48,4 @@ public @interface NoArgsConstructor { * Sets the access level of the constructor. By default, generated constructors are {@code public}. */ AccessLevel access() default lombok.AccessLevel.PUBLIC; - - /** - * Constructors are generated with the {@link java.beans.ConstructorProperties} annotation. - * However, this annotation is new in 1.6 which means those compiling for 1.5 will need - * to set this value to true. - * - * @deprecated Java 1.5 has already been end-of-lifed. As java 1.5 loses ground this - * method will eventually be removed. - */ - @Deprecated - boolean suppressConstructorProperties() default false; } diff --git a/src/core/lombok/eclipse/handlers/HandleConstructor.java b/src/core/lombok/eclipse/handlers/HandleConstructor.java index de6bb048..c780d4ef 100644 --- a/src/core/lombok/eclipse/handlers/HandleConstructor.java +++ b/src/core/lombok/eclipse/handlers/HandleConstructor.java @@ -26,6 +26,7 @@ import static lombok.eclipse.handlers.EclipseHandlerUtil.*; import java.lang.reflect.Modifier; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.List; @@ -45,6 +46,7 @@ import org.eclipse.jdt.internal.compiler.ast.ASTNode; import org.eclipse.jdt.internal.compiler.ast.AllocationExpression; import org.eclipse.jdt.internal.compiler.ast.Annotation; import org.eclipse.jdt.internal.compiler.ast.Argument; +import org.eclipse.jdt.internal.compiler.ast.ArrayInitializer; import org.eclipse.jdt.internal.compiler.ast.Assignment; import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration; import org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration; @@ -54,10 +56,13 @@ import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration; import org.eclipse.jdt.internal.compiler.ast.FieldReference; import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration; import org.eclipse.jdt.internal.compiler.ast.ParameterizedSingleTypeReference; +import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference; import org.eclipse.jdt.internal.compiler.ast.ReturnStatement; +import org.eclipse.jdt.internal.compiler.ast.SingleMemberAnnotation; import org.eclipse.jdt.internal.compiler.ast.SingleNameReference; import org.eclipse.jdt.internal.compiler.ast.SingleTypeReference; import org.eclipse.jdt.internal.compiler.ast.Statement; +import org.eclipse.jdt.internal.compiler.ast.StringLiteral; import org.eclipse.jdt.internal.compiler.ast.ThisReference; import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; import org.eclipse.jdt.internal.compiler.ast.TypeParameter; @@ -70,11 +75,12 @@ public class HandleConstructor { public static class HandleNoArgsConstructor implements EclipseAnnotationHandler<NoArgsConstructor> { @Override public boolean handle(AnnotationValues<NoArgsConstructor> annotation, Annotation ast, EclipseNode annotationNode) { EclipseNode typeNode = annotationNode.up(); - List<EclipseNode> fields = new ArrayList<EclipseNode>(); NoArgsConstructor ann = annotation.getInstance(); AccessLevel level = ann.access(); String staticName = ann.staticName(); - new HandleConstructor().generateConstructor(level, typeNode, fields, staticName, false, ast); + if (level == AccessLevel.NONE) return true; + List<EclipseNode> fields = new ArrayList<EclipseNode>(); + new HandleConstructor().generateConstructor(level, typeNode, fields, staticName, false, false, ast); return true; } } @@ -83,6 +89,12 @@ public class HandleConstructor { public static class HandleRequiredArgsConstructor implements EclipseAnnotationHandler<RequiredArgsConstructor> { @Override public boolean handle(AnnotationValues<RequiredArgsConstructor> annotation, Annotation ast, EclipseNode annotationNode) { EclipseNode typeNode = annotationNode.up(); + RequiredArgsConstructor ann = annotation.getInstance(); + AccessLevel level = ann.access(); + String staticName = ann.staticName(); + @SuppressWarnings("deprecation") + boolean suppressConstructorProperties = ann.suppressConstructorProperties(); + if (level == AccessLevel.NONE) return true; List<EclipseNode> fields = new ArrayList<EclipseNode>(); for (EclipseNode child : typeNode.down()) { if (child.getKind() != Kind.FIELD) continue; @@ -95,10 +107,7 @@ public class HandleConstructor { boolean isNonNull = findAnnotations(fieldDecl, TransformationsUtil.NON_NULL_PATTERN).length != 0; if ((isFinal || isNonNull) && fieldDecl.initialization == null) fields.add(child); } - RequiredArgsConstructor ann = annotation.getInstance(); - AccessLevel level = ann.access(); - String staticName = ann.staticName(); - new HandleConstructor().generateConstructor(level, typeNode, fields, staticName, false, ast); + new HandleConstructor().generateConstructor(level, typeNode, fields, staticName, false, suppressConstructorProperties, ast); return true; } } @@ -107,6 +116,12 @@ public class HandleConstructor { public static class HandleAllArgsConstructor implements EclipseAnnotationHandler<AllArgsConstructor> { @Override public boolean handle(AnnotationValues<AllArgsConstructor> annotation, Annotation ast, EclipseNode annotationNode) { EclipseNode typeNode = annotationNode.up(); + AllArgsConstructor ann = annotation.getInstance(); + AccessLevel level = ann.access(); + String staticName = ann.staticName(); + @SuppressWarnings("deprecation") + boolean suppressConstructorProperties = ann.suppressConstructorProperties(); + if (level == AccessLevel.NONE) return true; List<EclipseNode> fields = new ArrayList<EclipseNode>(); for (EclipseNode child : typeNode.down()) { if (child.getKind() != Kind.FIELD) continue; @@ -117,15 +132,12 @@ public class HandleConstructor { if ((fieldDecl.modifiers & ClassFileConstants.AccStatic) != 0) continue; fields.add(child); } - AllArgsConstructor ann = annotation.getInstance(); - AccessLevel level = ann.access(); - String staticName = ann.staticName(); - new HandleConstructor().generateConstructor(level, typeNode, fields, staticName, false, ast); + new HandleConstructor().generateConstructor(level, typeNode, fields, staticName, false, suppressConstructorProperties, ast); return true; } } - public void generateConstructor(AccessLevel level, EclipseNode typeNode, List<EclipseNode> fields, String staticName, boolean skipIfConstructorExists, ASTNode source) { + public void generateConstructor(AccessLevel level, EclipseNode typeNode, List<EclipseNode> fields, String staticName, boolean skipIfConstructorExists, boolean suppressConstructorProperties, ASTNode source) { if (skipIfConstructorExists && constructorExists(typeNode) != MemberExistsResult.NOT_EXISTS) return; if (skipIfConstructorExists) { for (EclipseNode child : typeNode.down()) { @@ -140,7 +152,7 @@ public class HandleConstructor { boolean staticConstrRequired = staticName != null && !staticName.equals(""); - ConstructorDeclaration constr = createConstructor(staticConstrRequired ? AccessLevel.PRIVATE : level, typeNode, fields, source); + ConstructorDeclaration constr = createConstructor(staticConstrRequired ? AccessLevel.PRIVATE : level, typeNode, fields, suppressConstructorProperties, source); injectMethod(typeNode, constr); if (staticConstrRequired) { MethodDeclaration staticConstr = createStaticConstructor(level, staticName, typeNode, fields, source); @@ -148,8 +160,42 @@ public class HandleConstructor { } } + private static final char[][] JAVA_BEANS_CONSTRUCTORPROPERTIES = new char[][] { "java".toCharArray(), "beans".toCharArray(), "ConstructorProperties".toCharArray() }; + private static Annotation[] createConstructorProperties(ASTNode source, Annotation[] originalAnnotationArray, Collection<EclipseNode> fields) { + if (fields.isEmpty()) return originalAnnotationArray; + + int pS = source.sourceStart, pE = source.sourceEnd; + long p = (long)pS << 32 | pE; + long[] poss = new long[3]; + Arrays.fill(poss, p); + QualifiedTypeReference constructorPropertiesType = new QualifiedTypeReference(JAVA_BEANS_CONSTRUCTORPROPERTIES, poss); + Eclipse.setGeneratedBy(constructorPropertiesType, source); + SingleMemberAnnotation ann = new SingleMemberAnnotation(constructorPropertiesType, pS); + ann.declarationSourceEnd = pE; + + ArrayInitializer fieldNames = new ArrayInitializer(); + fieldNames.sourceStart = pS; + fieldNames.sourceEnd = pE; + fieldNames.expressions = new Expression[fields.size()]; + + int ctr = 0; + for (EclipseNode field : fields) { + fieldNames.expressions[ctr] = new StringLiteral(field.getName().toCharArray(), pS, pE, 0); + Eclipse.setGeneratedBy(fieldNames.expressions[ctr], source); + ctr++; + } + + ann.memberValue = fieldNames; + Eclipse.setGeneratedBy(ann, source); + Eclipse.setGeneratedBy(ann.memberValue, source); + if (originalAnnotationArray == null) return new Annotation[] { ann }; + Annotation[] newAnnotationArray = Arrays.copyOf(originalAnnotationArray, originalAnnotationArray.length + 1); + newAnnotationArray[originalAnnotationArray.length] = ann; + return newAnnotationArray; + } + private ConstructorDeclaration createConstructor(AccessLevel level, - EclipseNode type, Collection<EclipseNode> fields, ASTNode source) { + EclipseNode type, Collection<EclipseNode> fields, boolean suppressConstructorProperties, ASTNode source) { long p = (long)source.sourceStart << 32 | source.sourceEnd; ConstructorDeclaration constructor = new ConstructorDeclaration( @@ -201,6 +247,11 @@ public class HandleConstructor { nullChecks.addAll(assigns); constructor.statements = nullChecks.isEmpty() ? null : nullChecks.toArray(new Statement[nullChecks.size()]); constructor.arguments = params.isEmpty() ? null : params.toArray(new Argument[params.size()]); + + if (!suppressConstructorProperties && level != AccessLevel.PRIVATE) { + constructor.annotations = createConstructorProperties(source, constructor.annotations, fields); + } + return constructor; } diff --git a/src/core/lombok/eclipse/handlers/HandleData.java b/src/core/lombok/eclipse/handlers/HandleData.java index dbbb91f0..ab1d7c28 100644 --- a/src/core/lombok/eclipse/handlers/HandleData.java +++ b/src/core/lombok/eclipse/handlers/HandleData.java @@ -83,7 +83,7 @@ public class HandleData implements EclipseAnnotationHandler<Data> { //for whatever reason, though you can find callers of that one by focusing on the class name itself //and hitting 'find callers'. - new HandleConstructor().generateConstructor(AccessLevel.PUBLIC, typeNode, nodesForConstructor, ann.staticConstructor(), true, ast); + new HandleConstructor().generateConstructor(AccessLevel.PUBLIC, typeNode, nodesForConstructor, ann.staticConstructor(), true, false, ast); for (Map.Entry<EclipseNode, Boolean> field : gettersAndSetters.entrySet()) { new HandleGetter().generateGetterForField(field.getKey(), annotationNode.get(), AccessLevel.PUBLIC, true); diff --git a/src/core/lombok/javac/handlers/HandleConstructor.java b/src/core/lombok/javac/handlers/HandleConstructor.java index 2f4a8474..4331761f 100644 --- a/src/core/lombok/javac/handlers/HandleConstructor.java +++ b/src/core/lombok/javac/handlers/HandleConstructor.java @@ -59,11 +59,12 @@ public class HandleConstructor { @Override public boolean handle(AnnotationValues<NoArgsConstructor> annotation, JCAnnotation ast, JavacNode annotationNode) { markAnnotationAsProcessed(annotationNode, NoArgsConstructor.class); JavacNode typeNode = annotationNode.up(); - List<JavacNode> fields = List.nil(); NoArgsConstructor ann = annotation.getInstance(); AccessLevel level = ann.access(); String staticName = ann.staticName(); - new HandleConstructor().generateConstructor(level, typeNode, fields, staticName, false); + if (level == AccessLevel.NONE) return true; + List<JavacNode> fields = List.nil(); + new HandleConstructor().generateConstructor(level, typeNode, fields, staticName, false, false); return true; } } @@ -73,6 +74,12 @@ public class HandleConstructor { @Override public boolean handle(AnnotationValues<RequiredArgsConstructor> annotation, JCAnnotation ast, JavacNode annotationNode) { markAnnotationAsProcessed(annotationNode, RequiredArgsConstructor.class); JavacNode typeNode = annotationNode.up(); + RequiredArgsConstructor ann = annotation.getInstance(); + AccessLevel level = ann.access(); + String staticName = ann.staticName(); + @SuppressWarnings("deprecation") + boolean suppressConstructorProperties = ann.suppressConstructorProperties(); + if (level == AccessLevel.NONE) return true; List<JavacNode> fields = List.nil(); for (JavacNode child : typeNode.down()) { if (child.getKind() != Kind.FIELD) continue; @@ -86,10 +93,7 @@ public class HandleConstructor { boolean isNonNull = !findAnnotations(child, TransformationsUtil.NON_NULL_PATTERN).isEmpty(); if ((isFinal || isNonNull) && fieldDecl.init == null) fields = fields.append(child); } - RequiredArgsConstructor ann = annotation.getInstance(); - AccessLevel level = ann.access(); - String staticName = ann.staticName(); - new HandleConstructor().generateConstructor(level, typeNode, fields, staticName, false); + new HandleConstructor().generateConstructor(level, typeNode, fields, staticName, false, suppressConstructorProperties); return true; } } @@ -99,6 +103,12 @@ public class HandleConstructor { @Override public boolean handle(AnnotationValues<AllArgsConstructor> annotation, JCAnnotation ast, JavacNode annotationNode) { markAnnotationAsProcessed(annotationNode, AllArgsConstructor.class); JavacNode typeNode = annotationNode.up(); + AllArgsConstructor ann = annotation.getInstance(); + AccessLevel level = ann.access(); + String staticName = ann.staticName(); + @SuppressWarnings("deprecation") + boolean suppressConstructorProperties = ann.suppressConstructorProperties(); + if (level == AccessLevel.NONE) return true; List<JavacNode> fields = List.nil(); for (JavacNode child : typeNode.down()) { if (child.getKind() != Kind.FIELD) continue; @@ -110,15 +120,12 @@ public class HandleConstructor { if ((fieldFlags & Flags.STATIC) != 0) continue; fields = fields.append(child); } - AllArgsConstructor ann = annotation.getInstance(); - AccessLevel level = ann.access(); - String staticName = ann.staticName(); - new HandleConstructor().generateConstructor(level, typeNode, fields, staticName, false); + new HandleConstructor().generateConstructor(level, typeNode, fields, staticName, false, suppressConstructorProperties); return true; } } - public void generateConstructor(AccessLevel level, JavacNode typeNode, List<JavacNode> fields, String staticName, boolean skipIfConstructorExists) { + public void generateConstructor(AccessLevel level, JavacNode typeNode, List<JavacNode> fields, String staticName, boolean skipIfConstructorExists, boolean suppressConstructorProperties) { if (skipIfConstructorExists && constructorExists(typeNode) != MemberExistsResult.NOT_EXISTS) return; if (skipIfConstructorExists) { for (JavacNode child : typeNode.down()) { @@ -133,7 +140,7 @@ public class HandleConstructor { boolean staticConstrRequired = staticName != null && !staticName.equals(""); - JCMethodDecl constr = createConstructor(staticConstrRequired ? AccessLevel.PRIVATE : level, typeNode, fields); + JCMethodDecl constr = createConstructor(staticConstrRequired ? AccessLevel.PRIVATE : level, typeNode, fields, suppressConstructorProperties); injectMethod(typeNode, constr); if (staticConstrRequired) { JCMethodDecl staticConstr = createStaticConstructor(staticName, level, typeNode, fields); @@ -141,7 +148,20 @@ public class HandleConstructor { } } - private JCMethodDecl createConstructor(AccessLevel level, JavacNode typeNode, List<JavacNode> fields) { + private static void addConstructorProperties(JCModifiers mods, JavacNode node, List<JavacNode> fields) { + if (fields.isEmpty()) return; + TreeMaker maker = node.getTreeMaker(); + JCExpression constructorPropertiesType = chainDots(maker, node, "java", "beans", "ConstructorProperties"); + List<JCExpression> fieldNames = List.nil(); + for (JavacNode field : fields) { + fieldNames = fieldNames.append(maker.Literal(field.getName())); + } + JCExpression fieldNamesArray = maker.NewArray(null, List.<JCExpression>nil(), fieldNames); + JCAnnotation annotation = maker.Annotation(constructorPropertiesType, List.of(fieldNamesArray)); + mods.annotations = mods.annotations.append(annotation); + } + + private JCMethodDecl createConstructor(AccessLevel level, JavacNode typeNode, List<JavacNode> fields, boolean suppressConstructorProperties) { TreeMaker maker = typeNode.getTreeMaker(); JCClassDecl type = (JCClassDecl) typeNode.get(); @@ -166,6 +186,10 @@ public class HandleConstructor { } JCModifiers mods = maker.Modifiers(toJavacModifier(level)); + if (!suppressConstructorProperties && level != AccessLevel.PRIVATE) { + addConstructorProperties(mods, typeNode, fields); + } + return maker.MethodDef(mods, typeNode.toName("<init>"), null, type.typarams, params, List.<JCExpression>nil(), maker.Block(0L, nullChecks.appendList(assigns)), null); } diff --git a/src/core/lombok/javac/handlers/HandleData.java b/src/core/lombok/javac/handlers/HandleData.java index 3bdd2dce..e20b230e 100644 --- a/src/core/lombok/javac/handlers/HandleData.java +++ b/src/core/lombok/javac/handlers/HandleData.java @@ -78,7 +78,7 @@ public class HandleData implements JavacAnnotationHandler<Data> { String staticConstructorName = annotation.getInstance().staticConstructor(); - new HandleConstructor().generateConstructor(AccessLevel.PUBLIC, typeNode, nodesForConstructor, staticConstructorName, true); + new HandleConstructor().generateConstructor(AccessLevel.PUBLIC, typeNode, nodesForConstructor, staticConstructorName, true, false); for (Map.Entry<JavacNode, Boolean> field : gettersAndSetters.entrySet()) { new HandleGetter().generateGetterForField(field.getKey(), annotationNode.get(), AccessLevel.PUBLIC, true); |