aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorReinier Zwitserloot <reinier@zwitserloot.com>2013-02-11 22:34:48 +0100
committerReinier Zwitserloot <reinier@zwitserloot.com>2013-02-11 22:34:48 +0100
commitaafd83079a3000d3deb6e40a182849da2509fbfb (patch)
treecf87951eee9bb098bb96ecc3c02c6f1ab34c405d /src
parentef8769d3180b2c6de91a64f69dfa23a2e6e449b9 (diff)
downloadlombok-aafd83079a3000d3deb6e40a182849da2509fbfb.tar.gz
lombok-aafd83079a3000d3deb6e40a182849da2509fbfb.tar.bz2
lombok-aafd83079a3000d3deb6e40a182849da2509fbfb.zip
BIG commit:
* re-introduction of onMethod/onConstructor/onParam * tests checking error/warnings rewritten to be more heuristic, in order to accomodate difference in messaging between java6 and java 7 * Ability to eliminate java's own output of erroneous error messages (heh); i.e. those messages that are invalidated by lombok's actions. This mechanism is used for onMethod/onConstructor/onParam * First steps to unifying a billion setGeneratedBy calls into a single visitor traversal for eclipse' HandleGetter/Setter/Constructor/Wither * To simplify 'zooming in' the tests on just a few files, added an 'accept' mechanism. * Updated copyright headers of website to 2013.
Diffstat (limited to 'src')
-rw-r--r--src/core/lombok/AllArgsConstructor.java16
-rw-r--r--src/core/lombok/Getter.java16
-rw-r--r--src/core/lombok/NoArgsConstructor.java16
-rw-r--r--src/core/lombok/RequiredArgsConstructor.java16
-rw-r--r--src/core/lombok/Setter.java21
-rw-r--r--src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java122
-rw-r--r--src/core/lombok/eclipse/handlers/HandleConstructor.java75
-rw-r--r--src/core/lombok/eclipse/handlers/HandleData.java6
-rw-r--r--src/core/lombok/eclipse/handlers/HandleGetter.java84
-rw-r--r--src/core/lombok/eclipse/handlers/HandleSetter.java54
-rw-r--r--src/core/lombok/eclipse/handlers/HandleValue.java7
-rw-r--r--src/core/lombok/eclipse/handlers/HandleWither.java43
-rw-r--r--src/core/lombok/experimental/Wither.java21
-rw-r--r--src/core/lombok/javac/CapturingDiagnosticListener.java132
-rw-r--r--src/core/lombok/javac/JavacAST.java59
-rw-r--r--src/core/lombok/javac/JavacNode.java14
-rw-r--r--src/core/lombok/javac/handlers/HandleConstructor.java23
-rw-r--r--src/core/lombok/javac/handlers/HandleGetter.java32
-rw-r--r--src/core/lombok/javac/handlers/HandleSetter.java29
-rw-r--r--src/core/lombok/javac/handlers/HandleWither.java38
-rw-r--r--src/core/lombok/javac/handlers/JavacHandlerUtil.java70
-rw-r--r--src/stubs/com/sun/tools/javac/parser/EndPosParser.java3
-rw-r--r--src/stubs/com/sun/tools/javac/parser/Lexer.java3
-rw-r--r--src/stubs/com/sun/tools/javac/parser/Parser.java21
-rw-r--r--src/stubs/com/sun/tools/javac/parser/ParserFactory.java3
-rw-r--r--src/stubs/com/sun/tools/javac/util/BaseFileObject.java8
26 files changed, 699 insertions, 233 deletions
diff --git a/src/core/lombok/AllArgsConstructor.java b/src/core/lombok/AllArgsConstructor.java
index 2147bdae..068b7a68 100644
--- a/src/core/lombok/AllArgsConstructor.java
+++ b/src/core/lombok/AllArgsConstructor.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010-2012 The Project Lombok Authors.
+ * Copyright (C) 2010-2013 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -49,6 +49,11 @@ public @interface AllArgsConstructor {
String staticName() default "";
/**
+ * Any annotations listed here are put on the generated constructor. The syntax for this feature is: {@code @AllArgsConstructor(onConstructor=@_({@AnnotationsGoHere}))}
+ */
+ AnyAnnotation[] onConstructor() default {};
+
+ /**
* Sets the access level of the constructor. By default, generated constructors are {@code public}.
*/
AccessLevel access() default lombok.AccessLevel.PUBLIC;
@@ -63,4 +68,13 @@ public @interface AllArgsConstructor {
*/
@Deprecated
boolean suppressConstructorProperties() default false;
+
+ /**
+ * Placeholder annotation to enable the placement of annotations on the generated code.
+ * @deprecated Don't use this annotation, ever - Read the documentation.
+ */
+ @Deprecated
+ @Retention(RetentionPolicy.SOURCE)
+ @Target({})
+ @interface AnyAnnotation {}
}
diff --git a/src/core/lombok/Getter.java b/src/core/lombok/Getter.java
index fa12ce1b..57f5e40a 100644
--- a/src/core/lombok/Getter.java
+++ b/src/core/lombok/Getter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2012 The Project Lombok Authors.
+ * Copyright (C) 2009-2013 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -57,5 +57,19 @@ public @interface Getter {
*/
lombok.AccessLevel value() default lombok.AccessLevel.PUBLIC;
+ /**
+ * Any annotations listed here are put on the generated method. The syntax for this feature is: {@code @Getter(onMethod=@_({@AnnotationsGoHere}))}
+ */
+ AnyAnnotation[] onMethod() default @AnyAnnotation;
+
boolean lazy() default false;
+
+ /**
+ * Placeholder annotation to enable the placement of annotations on the generated code.
+ * @deprecated Don't use this annotation, ever - Read the documentation.
+ */
+ @Deprecated
+ @Retention(RetentionPolicy.SOURCE)
+ @Target({})
+ @interface AnyAnnotation {}
}
diff --git a/src/core/lombok/NoArgsConstructor.java b/src/core/lombok/NoArgsConstructor.java
index ba53e39f..bbf2d9e6 100644
--- a/src/core/lombok/NoArgsConstructor.java
+++ b/src/core/lombok/NoArgsConstructor.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010-2012 The Project Lombok Authors.
+ * Copyright (C) 2010-2013 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -51,7 +51,21 @@ public @interface NoArgsConstructor {
String staticName() default "";
/**
+ * Any annotations listed here are put on the generated constructor. The syntax for this feature is: {@code @NoArgsConstructor(onConstructor=@_({@AnnotationsGoHere}))}
+ */
+ AnyAnnotation[] onConstructor() default {};
+
+ /**
* Sets the access level of the constructor. By default, generated constructors are {@code public}.
*/
AccessLevel access() default lombok.AccessLevel.PUBLIC;
+
+ /**
+ * Placeholder annotation to enable the placement of annotations on the generated code.
+ * @deprecated Don't use this annotation, ever - Read the documentation.
+ */
+ @Deprecated
+ @Retention(RetentionPolicy.SOURCE)
+ @Target({})
+ @interface AnyAnnotation {}
}
diff --git a/src/core/lombok/RequiredArgsConstructor.java b/src/core/lombok/RequiredArgsConstructor.java
index afe9773e..31c4b81d 100644
--- a/src/core/lombok/RequiredArgsConstructor.java
+++ b/src/core/lombok/RequiredArgsConstructor.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010-2012 The Project Lombok Authors.
+ * Copyright (C) 2010-2013 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -49,6 +49,11 @@ public @interface RequiredArgsConstructor {
String staticName() default "";
/**
+ * Any annotations listed here are put on the generated constructor. The syntax for this feature is: {@code @RequiredArgsConstructor(onConstructor=@_({@AnnotationsGoHere}))}
+ */
+ AnyAnnotation[] onConstructor() default {};
+
+ /**
* Sets the access level of the constructor. By default, generated constructors are {@code public}.
*/
AccessLevel access() default lombok.AccessLevel.PUBLIC;
@@ -63,4 +68,13 @@ public @interface RequiredArgsConstructor {
*/
@Deprecated
boolean suppressConstructorProperties() default false;
+
+ /**
+ * Placeholder annotation to enable the placement of annotations on the generated code.
+ * @deprecated Don't use this annotation, ever - Read the documentation.
+ */
+ @Deprecated
+ @Retention(RetentionPolicy.SOURCE)
+ @Target({})
+ @interface AnyAnnotation {}
}
diff --git a/src/core/lombok/Setter.java b/src/core/lombok/Setter.java
index 59ed9346..22622520 100644
--- a/src/core/lombok/Setter.java
+++ b/src/core/lombok/Setter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2012 The Project Lombok Authors.
+ * Copyright (C) 2009-2013 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -57,4 +57,23 @@ public @interface Setter {
* If you want your setter to be non-public, you can specify an alternate access level here.
*/
lombok.AccessLevel value() default lombok.AccessLevel.PUBLIC;
+
+ /**
+ * Any annotations listed here are put on the generated method. The syntax for this feature is: {@code @Setter(onMethod=@_({@AnnotationsGoHere}))}
+ */
+ AnyAnnotation[] onMethod() default {};
+
+ /**
+ * Any annotations listed here are put on the generated method's parameter. The syntax for this feature is: {@code @Setter(onParam=@_({@AnnotationsGoHere}))}
+ */
+ AnyAnnotation[] onParam() default {};
+
+ /**
+ * Placeholder annotation to enable the placement of annotations on the generated code.
+ * @deprecated Don't use this annotation, ever - Read the documentation.
+ */
+ @Deprecated
+ @Retention(RetentionPolicy.SOURCE)
+ @Target({})
+ @interface AnyAnnotation {}
} \ No newline at end of file
diff --git a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java
index 96795fe1..78780522 100644
--- a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java
+++ b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2012 The Project Lombok Authors.
+ * Copyright (C) 2009-2013 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -473,7 +473,7 @@ public class EclipseHandlerUtil {
}
}
if (allNull) return null;
- return result.toArray(EMPTY_ANNOTATION_ARRAY);
+ return result.toArray(new Annotation[0]);
}
public static boolean hasAnnotation(Class<? extends java.lang.annotation.Annotation> type, EclipseNode node) {
@@ -1492,40 +1492,102 @@ public class EclipseHandlerUtil {
intLiteralFactoryMethod = intLiteralFactoryMethod_;
}
- private static final Annotation[] EMPTY_ANNOTATION_ARRAY = new Annotation[0];
- static Annotation[] getAndRemoveAnnotationParameter(Annotation annotation, String annotationName) {
-
- List<Annotation> result = new ArrayList<Annotation>();
- if (annotation instanceof NormalAnnotation) {
- NormalAnnotation normalAnnotation = (NormalAnnotation)annotation;
- MemberValuePair[] memberValuePairs = normalAnnotation.memberValuePairs;
- List<MemberValuePair> pairs = new ArrayList<MemberValuePair>();
- if (memberValuePairs != null) for (MemberValuePair memberValuePair : memberValuePairs) {
- if (annotationName.equals(new String(memberValuePair.name))) {
- Expression value = memberValuePair.value;
- if (value instanceof ArrayInitializer) {
- ArrayInitializer array = (ArrayInitializer) value;
- for(Expression expression : array.expressions) {
- if (expression instanceof Annotation) {
- result.add((Annotation)expression);
- }
- }
- }
- else if (value instanceof Annotation) {
- result.add((Annotation)value);
- }
- continue;
+ private static boolean isAllUnderscores(char[] in) {
+ if (in == null || in.length == 0) return false;
+ for (char c : in) if (c != '_') return false;
+ return true;
+ }
+
+ static List<Annotation> unboxAndRemoveAnnotationParameter(Annotation annotation, String annotationName, String errorName, EclipseNode errorNode) {
+ if ("value".equals(annotationName)) {
+ // We can't unbox this, because SingleMemberAnnotation REQUIRES a value, and this method
+ // is supposed to remove the value. That means we need to replace the SMA with either
+ // MarkerAnnotation or NormalAnnotation and that is beyond the scope of this method as we
+ // don't need that at the time of writing this method; we only unbox onMethod, onParameter
+ // and onConstructor. Let's exit early and very obviously:
+ throw new UnsupportedOperationException("Lombok cannot unbox 'value' from SingleMemberAnnotation at this time.");
+ }
+ if (!NormalAnnotation.class.equals(annotation.getClass())) {
+ // Prevent MarkerAnnotation, SingleMemberAnnotation, and
+ // CompletionOnAnnotationMemberValuePair from triggering this handler.
+ return Collections.emptyList();
+ }
+
+ NormalAnnotation normalAnnotation = (NormalAnnotation) annotation;
+ MemberValuePair[] pairs = normalAnnotation.memberValuePairs;
+
+ if (pairs == null) return Collections.emptyList();
+
+ char[] nameAsCharArray = annotationName.toCharArray();
+
+ for (int i = 0; i < pairs.length; i++) {
+ if (pairs[i].name == null || !Arrays.equals(nameAsCharArray, pairs[i].name)) continue;
+ Expression value = pairs[i].value;
+ MemberValuePair[] newPairs = new MemberValuePair[pairs.length - 1];
+ if (i > 0) System.arraycopy(pairs, 0, newPairs, 0, i);
+ if (i < pairs.length - 1) System.arraycopy(pairs, i + 1, newPairs, i, pairs.length - i - 1);
+ normalAnnotation.memberValuePairs = newPairs;
+ // We have now removed the annotation parameter and stored '@_({... annotations ...})',
+ // which we must now unbox.
+ if (!(value instanceof Annotation)) {
+ errorNode.addError("The correct format is " + errorName + "@_({@SomeAnnotation, @SomeOtherAnnotation}))");
+ return Collections.emptyList();
+ }
+
+ Annotation atUnderscore = (Annotation) value;
+ if (!(atUnderscore.type instanceof SingleTypeReference) ||
+ !isAllUnderscores(((SingleTypeReference) atUnderscore.type).token)) {
+ errorNode.addError("The correct format is " + errorName + "@_({@SomeAnnotation, @SomeOtherAnnotation}))");
+ return Collections.emptyList();
+ }
+
+ if (atUnderscore instanceof MarkerAnnotation) {
+ // It's @getter(onMethod=@_). This is weird, but fine.
+ return Collections.emptyList();
+ }
+
+ Expression content = null;
+
+ if (atUnderscore instanceof NormalAnnotation) {
+ MemberValuePair[] mvps = ((NormalAnnotation) atUnderscore).memberValuePairs;
+ if (mvps == null || mvps.length == 0) {
+ // It's @getter(onMethod=@_()). This is weird, but fine.
+ return Collections.emptyList();
+ }
+ if (mvps.length == 1 && Arrays.equals("value".toCharArray(), mvps[0].name)) {
+ content = mvps[0].value;
}
- pairs.add(memberValuePair);
}
- if (!result.isEmpty()) {
- normalAnnotation.memberValuePairs = pairs.isEmpty() ? null : pairs.toArray(new MemberValuePair[0]);
- return result.toArray(EMPTY_ANNOTATION_ARRAY);
+ if (atUnderscore instanceof SingleMemberAnnotation) {
+ content = ((SingleMemberAnnotation) atUnderscore).memberValue;
+ }
+
+ if (content == null) {
+ errorNode.addError("The correct format is " + errorName + "@_({@SomeAnnotation, @SomeOtherAnnotation}))");
+ return Collections.emptyList();
+ }
+
+ if (content instanceof Annotation) {
+ return Collections.singletonList((Annotation) content);
+ } else if (content instanceof ArrayInitializer) {
+ Expression[] expressions = ((ArrayInitializer) content).expressions;
+ List<Annotation> result = new ArrayList<Annotation>();
+ if (expressions != null) for (Expression ex : expressions) {
+ if (ex instanceof Annotation) result.add((Annotation) ex);
+ else {
+ errorNode.addError("The correct format is " + errorName + "@_({@SomeAnnotation, @SomeOtherAnnotation}))");
+ return Collections.emptyList();
+ }
+ }
+ return result;
+ } else {
+ errorNode.addError("The correct format is " + errorName + "@_({@SomeAnnotation, @SomeOtherAnnotation}))");
+ return Collections.emptyList();
}
}
- return EMPTY_ANNOTATION_ARRAY;
+ return Collections.emptyList();
}
static NameReference createNameReference(String name, Annotation source) {
diff --git a/src/core/lombok/eclipse/handlers/HandleConstructor.java b/src/core/lombok/eclipse/handlers/HandleConstructor.java
index 5d4656b6..8ccad77f 100644
--- a/src/core/lombok/eclipse/handlers/HandleConstructor.java
+++ b/src/core/lombok/eclipse/handlers/HandleConstructor.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010-2011 The Project Lombok Authors.
+ * Copyright (C) 2010-2013 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -79,7 +79,10 @@ public class HandleConstructor {
String staticName = ann.staticName();
if (level == AccessLevel.NONE) return;
List<EclipseNode> fields = new ArrayList<EclipseNode>();
- new HandleConstructor().generateConstructor(typeNode, level, fields, staticName, false, false, ast);
+
+ List<Annotation> onConstructor = unboxAndRemoveAnnotationParameter(ast, "onConstructor", "@NoArgsConstructor(onConstructor=", annotationNode);
+
+ new HandleConstructor().generateConstructor(typeNode, level, fields, staticName, false, false, onConstructor, ast);
}
}
@@ -94,7 +97,10 @@ public class HandleConstructor {
@SuppressWarnings("deprecation")
boolean suppressConstructorProperties = ann.suppressConstructorProperties();
if (level == AccessLevel.NONE) return;
- new HandleConstructor().generateConstructor(typeNode, level, findRequiredFields(typeNode), staticName, false, suppressConstructorProperties, ast);
+
+ List<Annotation> onConstructor = unboxAndRemoveAnnotationParameter(ast, "onConstructor", "@RequiredArgsConstructor(onConstructor=", annotationNode);
+
+ new HandleConstructor().generateConstructor(typeNode, level, findRequiredFields(typeNode), staticName, false, suppressConstructorProperties, onConstructor, ast);
}
}
@@ -137,7 +143,10 @@ public class HandleConstructor {
@SuppressWarnings("deprecation")
boolean suppressConstructorProperties = ann.suppressConstructorProperties();
if (level == AccessLevel.NONE) return;
- new HandleConstructor().generateConstructor(typeNode, level, findAllFields(typeNode), staticName, false, suppressConstructorProperties, ast);
+
+ List<Annotation> onConstructor = unboxAndRemoveAnnotationParameter(ast, "onConstructor", "@AllArgsConstructor(onConstructor=", annotationNode);
+
+ new HandleConstructor().generateConstructor(typeNode, level, findAllFields(typeNode), staticName, false, suppressConstructorProperties, onConstructor, ast);
}
}
@@ -155,15 +164,15 @@ public class HandleConstructor {
return true;
}
- public void generateRequiredArgsConstructor(EclipseNode typeNode, AccessLevel level, String staticName, boolean skipIfConstructorExists, ASTNode source) {
- generateConstructor(typeNode, level, findRequiredFields(typeNode), staticName, skipIfConstructorExists, false, source);
+ public void generateRequiredArgsConstructor(EclipseNode typeNode, AccessLevel level, String staticName, boolean skipIfConstructorExists, List<Annotation> onConstructor, ASTNode source) {
+ generateConstructor(typeNode, level, findRequiredFields(typeNode), staticName, skipIfConstructorExists, false, onConstructor, source);
}
- public void generateAllArgsConstructor(EclipseNode typeNode, AccessLevel level, String staticName, boolean skipIfConstructorExists, ASTNode source) {
- generateConstructor(typeNode, level, findAllFields(typeNode), staticName, skipIfConstructorExists, false, source);
+ public void generateAllArgsConstructor(EclipseNode typeNode, AccessLevel level, String staticName, boolean skipIfConstructorExists, List<Annotation> onConstructor, ASTNode source) {
+ generateConstructor(typeNode, level, findAllFields(typeNode), staticName, skipIfConstructorExists, false, onConstructor, source);
}
- public void generateConstructor(EclipseNode typeNode, AccessLevel level, List<EclipseNode> fields, String staticName, boolean skipIfConstructorExists, boolean suppressConstructorProperties, ASTNode source) {
+ public void generateConstructor(EclipseNode typeNode, AccessLevel level, List<EclipseNode> fields, String staticName, boolean skipIfConstructorExists, boolean suppressConstructorProperties, List<Annotation> onConstructor, ASTNode source) {
boolean staticConstrRequired = staticName != null && !staticName.equals("");
if (skipIfConstructorExists && constructorExists(typeNode) != MemberExistsResult.NOT_EXISTS) return;
@@ -187,7 +196,7 @@ public class HandleConstructor {
}
}
- ConstructorDeclaration constr = createConstructor(staticConstrRequired ? AccessLevel.PRIVATE : level, typeNode, fields, suppressConstructorProperties, source);
+ ConstructorDeclaration constr = createConstructor(staticConstrRequired ? AccessLevel.PRIVATE : level, typeNode, fields, suppressConstructorProperties, source, onConstructor);
injectMethod(typeNode, constr);
if (staticConstrRequired) {
MethodDeclaration staticConstr = createStaticConstructor(level, staticName, typeNode, fields, source);
@@ -196,8 +205,8 @@ 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;
+ private static Annotation[] createConstructorProperties(ASTNode source, Collection<EclipseNode> fields) {
+ if (fields.isEmpty()) return null;
int pS = source.sourceStart, pE = source.sourceEnd;
long p = (long)pS << 32 | pE;
@@ -223,14 +232,14 @@ public class HandleConstructor {
ann.memberValue = fieldNames;
setGeneratedBy(ann, source);
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;
+ return new Annotation[] { ann };
}
- private ConstructorDeclaration createConstructor(AccessLevel level,
- EclipseNode type, Collection<EclipseNode> fields, boolean suppressConstructorProperties, ASTNode source) {
+ private ConstructorDeclaration createConstructor(
+ AccessLevel level, EclipseNode type, Collection<EclipseNode> fields,
+ boolean suppressConstructorProperties, ASTNode source, List<Annotation> onConstructor) {
+
+ TypeDeclaration typeDeclaration = ((TypeDeclaration)type.get());
long p = (long)source.sourceStart << 32 | source.sourceEnd;
boolean isEnum = (((TypeDeclaration)type.get()).modifiers & ClassFileConstants.AccEnum) != 0;
@@ -239,12 +248,10 @@ public class HandleConstructor {
ConstructorDeclaration constructor = new ConstructorDeclaration(
((CompilationUnitDeclaration) type.top().get()).compilationResult);
- setGeneratedBy(constructor, source);
constructor.modifiers = toEclipseModifier(level);
- constructor.selector = ((TypeDeclaration)type.get()).name;
+ constructor.selector = typeDeclaration.name;
constructor.constructorCall = new ExplicitConstructorCall(ExplicitConstructorCall.ImplicitSuper);
- setGeneratedBy(constructor.constructorCall, source);
constructor.constructorCall.sourceStart = source.sourceStart;
constructor.constructorCall.sourceEnd = source.sourceEnd;
constructor.thrownExceptions = null;
@@ -261,19 +268,14 @@ public class HandleConstructor {
for (EclipseNode fieldNode : fields) {
FieldDeclaration field = (FieldDeclaration) fieldNode.get();
FieldReference thisX = new FieldReference(field.name, p);
- setGeneratedBy(thisX, source);
thisX.receiver = new ThisReference((int)(p >> 32), (int)p);
- setGeneratedBy(thisX.receiver, source);
SingleNameReference assignmentNameRef = new SingleNameReference(field.name, p);
- setGeneratedBy(assignmentNameRef, source);
Assignment assignment = new Assignment(thisX, assignmentNameRef, (int)p);
assignment.sourceStart = (int)(p >> 32); assignment.sourceEnd = assignment.statementEnd = (int)(p >> 32);
- setGeneratedBy(assignment, source);
assigns.add(assignment);
long fieldPos = (((long)field.sourceStart) << 32) | field.sourceEnd;
Argument parameter = new Argument(field.name, fieldPos, copyType(field.type, source), Modifier.FINAL);
- setGeneratedBy(parameter, source);
Annotation[] nonNulls = findAnnotations(field, TransformationsUtil.NON_NULL_PATTERN);
Annotation[] nullables = findAnnotations(field, TransformationsUtil.NULLABLE_PATTERN);
if (nonNulls.length != 0) {
@@ -289,10 +291,19 @@ public class HandleConstructor {
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 && !isLocalType(type)) {
- constructor.annotations = createConstructorProperties(source, constructor.annotations, fields);
+ /* Generate annotations that must be put on the generated method, and attach them. */ {
+ Annotation[] constructorProperties = null;
+ if (!suppressConstructorProperties && level != AccessLevel.PRIVATE && !isLocalType(type)) {
+ constructorProperties = createConstructorProperties(source, fields);
+ }
+
+ Annotation[] copiedAnnotations = copyAnnotations(source,
+ onConstructor.toArray(new Annotation[0]),
+ constructorProperties);
+ if (copiedAnnotations.length != 0) constructor.annotations = copiedAnnotations;
}
+ constructor.traverse(new SetGeneratedByVisitor(source), typeDeclaration.scope);
return constructor;
}
@@ -309,7 +320,6 @@ public class HandleConstructor {
MethodDeclaration constructor = new MethodDeclaration(
((CompilationUnitDeclaration) type.top().get()).compilationResult);
- setGeneratedBy(constructor, source);
constructor.modifiers = toEclipseModifier(level) | Modifier.STATIC;
TypeDeclaration typeDecl = (TypeDeclaration) type.get();
@@ -323,7 +333,6 @@ public class HandleConstructor {
}
constructor.returnType = new ParameterizedSingleTypeReference(typeDecl.name, refs, 0, p);
} else constructor.returnType = new SingleTypeReference(((TypeDeclaration)type.get()).name, p);
- setGeneratedBy(constructor.returnType, source);
constructor.annotations = null;
constructor.selector = name.toCharArray();
constructor.thrownExceptions = null;
@@ -336,18 +345,15 @@ public class HandleConstructor {
List<Expression> assigns = new ArrayList<Expression>();
AllocationExpression statement = new AllocationExpression();
statement.sourceStart = pS; statement.sourceEnd = pE;
- setGeneratedBy(statement, source);
statement.type = copyType(constructor.returnType, source);
for (EclipseNode fieldNode : fields) {
FieldDeclaration field = (FieldDeclaration) fieldNode.get();
long fieldPos = (((long)field.sourceStart) << 32) | field.sourceEnd;
SingleNameReference nameRef = new SingleNameReference(field.name, fieldPos);
- setGeneratedBy(nameRef, source);
assigns.add(nameRef);
Argument parameter = new Argument(field.name, fieldPos, copyType(field.type, source), Modifier.FINAL);
- setGeneratedBy(parameter, source);
Annotation[] copiedAnnotations = copyAnnotations(source, findAnnotations(field, TransformationsUtil.NON_NULL_PATTERN), findAnnotations(field, TransformationsUtil.NULLABLE_PATTERN));
if (copiedAnnotations.length != 0) parameter.annotations = copiedAnnotations;
@@ -357,7 +363,8 @@ public class HandleConstructor {
statement.arguments = assigns.isEmpty() ? null : assigns.toArray(new Expression[assigns.size()]);
constructor.arguments = params.isEmpty() ? null : params.toArray(new Argument[params.size()]);
constructor.statements = new Statement[] { new ReturnStatement(statement, (int)(p >> 32), (int)p) };
- setGeneratedBy(constructor.statements[0], source);
+
+ constructor.traverse(new SetGeneratedByVisitor(source), typeDecl.scope);
return constructor;
}
}
diff --git a/src/core/lombok/eclipse/handlers/HandleData.java b/src/core/lombok/eclipse/handlers/HandleData.java
index ba29b30b..3a43bd3f 100644
--- a/src/core/lombok/eclipse/handlers/HandleData.java
+++ b/src/core/lombok/eclipse/handlers/HandleData.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2011 The Project Lombok Authors.
+ * Copyright (C) 2009-2013 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -21,6 +21,8 @@
*/
package lombok.eclipse.handlers;
+import java.util.Collections;
+
import lombok.AccessLevel;
import lombok.Data;
import lombok.core.AnnotationValues;
@@ -62,6 +64,6 @@ public class HandleData extends EclipseAnnotationHandler<Data> {
new HandleSetter().generateSetterForType(typeNode, annotationNode, AccessLevel.PUBLIC, true);
new HandleEqualsAndHashCode().generateEqualsAndHashCodeForType(typeNode, annotationNode);
new HandleToString().generateToStringForType(typeNode, annotationNode);
- new HandleConstructor().generateRequiredArgsConstructor(typeNode, AccessLevel.PUBLIC, ann.staticConstructor(), true, ast);
+ new HandleConstructor().generateRequiredArgsConstructor(typeNode, AccessLevel.PUBLIC, ann.staticConstructor(), true, Collections.<Annotation>emptyList(), ast);
}
}
diff --git a/src/core/lombok/eclipse/handlers/HandleGetter.java b/src/core/lombok/eclipse/handlers/HandleGetter.java
index df05fc7e..7f788c5d 100644
--- a/src/core/lombok/eclipse/handlers/HandleGetter.java
+++ b/src/core/lombok/eclipse/handlers/HandleGetter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2012 The Project Lombok Authors.
+ * Copyright (C) 2009-2013 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -125,7 +125,7 @@ public class HandleGetter extends EclipseAnnotationHandler<Getter> {
return;
}
- createGetterForField(level, fieldNode, fieldNode, pos, false, lazy);
+ createGetterForField(level, fieldNode, fieldNode, pos, false, lazy, Collections.<Annotation>emptyList());
}
public void handle(AnnotationValues<Getter> annotation, Annotation ast, EclipseNode annotationNode) {
@@ -142,25 +142,30 @@ public class HandleGetter extends EclipseAnnotationHandler<Getter> {
if (node == null) return;
+ List<Annotation> onMethod = unboxAndRemoveAnnotationParameter(ast, "onMethod", "@Getter(onMethod=", annotationNode);
+
switch (node.getKind()) {
case FIELD:
- createGetterForFields(level, annotationNode.upFromAnnotationToFields(), annotationNode, annotationNode.get(), true, lazy);
+ createGetterForFields(level, annotationNode.upFromAnnotationToFields(), annotationNode, annotationNode.get(), true, lazy, onMethod);
break;
case TYPE:
+ if (!onMethod.isEmpty()) {
+ annotationNode.addError("'onMethod' is not supported for @Getter on a type.");
+ }
if (lazy) annotationNode.addError("'lazy' is not supported for @Getter on a type.");
generateGetterForType(node, annotationNode, level, false);
break;
}
}
- private void createGetterForFields(AccessLevel level, Collection<EclipseNode> fieldNodes, EclipseNode errorNode, ASTNode source, boolean whineIfExists, boolean lazy) {
+ private void createGetterForFields(AccessLevel level, Collection<EclipseNode> fieldNodes, EclipseNode errorNode, ASTNode source, boolean whineIfExists, boolean lazy, List<Annotation> onMethod) {
for (EclipseNode fieldNode : fieldNodes) {
- createGetterForField(level, fieldNode, errorNode, source, whineIfExists, lazy);
+ createGetterForField(level, fieldNode, errorNode, source, whineIfExists, lazy, onMethod);
}
}
private void createGetterForField(AccessLevel level,
- EclipseNode fieldNode, EclipseNode errorNode, ASTNode source, boolean whineIfExists, boolean lazy) {
+ EclipseNode fieldNode, EclipseNode errorNode, ASTNode source, boolean whineIfExists, boolean lazy, List<Annotation> onMethod) {
if (fieldNode.getKind() != Kind.FIELD) {
errorNode.addError("@Getter is only supported on a class or a field.");
return;
@@ -207,17 +212,7 @@ public class HandleGetter extends EclipseAnnotationHandler<Getter> {
}
}
- MethodDeclaration method = generateGetter((TypeDeclaration) fieldNode.up().get(), fieldNode, getterName, modifier, source, lazy);
-
- Annotation[] deprecated = null;
- if (isFieldDeprecated(fieldNode)) {
- deprecated = new Annotation[] { generateDeprecatedAnnotation(source) };
- }
-
- Annotation[] copiedAnnotations = copyAnnotations(source, findAnnotations(field, TransformationsUtil.NON_NULL_PATTERN), findAnnotations(field, Tr