aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoel Spilker <r.spilker@gmail.com>2012-01-24 02:52:13 +0100
committerRoel Spilker <r.spilker@gmail.com>2012-01-24 02:52:13 +0100
commit2242de2bf9886fc80858486bbb3aa171a5496885 (patch)
tree36f6795f3e00b1ab122fb2c1ac6d201a1660c89f
parent3e7bb145d3984d7472baa177ead3baf574d42e6b (diff)
downloadlombok-2242de2bf9886fc80858486bbb3aa171a5496885.tar.gz
lombok-2242de2bf9886fc80858486bbb3aa171a5496885.tar.bz2
lombok-2242de2bf9886fc80858486bbb3aa171a5496885.zip
Fix for issue 328: @Delegate on a field for which we also generate a getter will use the getter for delegation
-rw-r--r--src/core/lombok/eclipse/handlers/HandleGetter.java23
-rw-r--r--src/core/lombok/javac/handlers/HandleGetter.java27
-rw-r--r--src/eclipseAgent/lombok/eclipse/agent/PatchDelegate.java4
-rw-r--r--src/utils/lombok/eclipse/Eclipse.java5
-rw-r--r--test/transform/resource/after-delombok/DelegateOnGetter.java35
-rw-r--r--test/transform/resource/after-ecj/DelegateOnGetter.java1
-rw-r--r--test/transform/resource/after-eclipse/DelegateOnGetter.java40
-rw-r--r--test/transform/resource/before/DelegateOnGetter.java18
8 files changed, 149 insertions, 4 deletions
diff --git a/src/core/lombok/eclipse/handlers/HandleGetter.java b/src/core/lombok/eclipse/handlers/HandleGetter.java
index 1d59afb4..b7d9c5ed 100644
--- a/src/core/lombok/eclipse/handlers/HandleGetter.java
+++ b/src/core/lombok/eclipse/handlers/HandleGetter.java
@@ -24,18 +24,23 @@ package lombok.eclipse.handlers;
import static lombok.eclipse.Eclipse.*;
import static lombok.eclipse.handlers.EclipseHandlerUtil.*;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import lombok.AccessLevel;
+import lombok.Delegate;
import lombok.Getter;
+import lombok.core.AST.Kind;
import lombok.core.AnnotationValues;
import lombok.core.TransformationsUtil;
-import lombok.core.AST.Kind;
import lombok.eclipse.EclipseAnnotationHandler;
import lombok.eclipse.EclipseNode;
+import lombok.eclipse.agent.PatchDelegate;
+import lombok.eclipse.handlers.EclipseHandlerUtil.FieldAccess;
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
import org.eclipse.jdt.internal.compiler.ast.AllocationExpression;
@@ -69,6 +74,8 @@ import org.mangosdk.spi.ProviderFor;
*/
@ProviderFor(EclipseAnnotationHandler.class)
public class HandleGetter extends EclipseAnnotationHandler<Getter> {
+ private static final Annotation[] EMPTY_ANNOTATIONS_ARRAY = new Annotation[0];
+
public boolean generateGetterForType(EclipseNode typeNode, EclipseNode pos, AccessLevel level, boolean checkForTypeLevelGetter) {
if (checkForTypeLevelGetter) {
if (typeNode != null) for (EclipseNode child : typeNode.down()) {
@@ -205,13 +212,25 @@ public class HandleGetter extends EclipseAnnotationHandler<Getter> {
}
MethodDeclaration method = generateGetter((TypeDeclaration) fieldNode.up().get(), fieldNode, getterName, modifier, source, lazy);
- Annotation[] copiedAnnotations = copyAnnotations(source, findAnnotations(field, TransformationsUtil.NON_NULL_PATTERN), findAnnotations(field, TransformationsUtil.NULLABLE_PATTERN));
+ Annotation[] copiedAnnotations = copyAnnotations(source, findAnnotations(field, TransformationsUtil.NON_NULL_PATTERN), findAnnotations(field, TransformationsUtil.NULLABLE_PATTERN), findDelegatesAndMarkAsHandled(fieldNode));
if (copiedAnnotations.length != 0) {
method.annotations = copiedAnnotations;
}
injectMethod(fieldNode.up(), method);
}
+
+ private static Annotation[] findDelegatesAndMarkAsHandled(EclipseNode fieldNode) {
+ List<Annotation> delegates = new ArrayList<Annotation>();
+ for (EclipseNode child : fieldNode.down()) {
+ if (annotationTypeMatches(Delegate.class, child)) {
+ Annotation delegate = (Annotation)child.get();
+ PatchDelegate.markHandled(delegate);
+ delegates.add(delegate);
+ }
+ }
+ return delegates.toArray(EMPTY_ANNOTATIONS_ARRAY);
+ }
private MethodDeclaration generateGetter(TypeDeclaration parent, EclipseNode fieldNode, String name, int modifier, ASTNode source, boolean lazy) {
diff --git a/src/core/lombok/javac/handlers/HandleGetter.java b/src/core/lombok/javac/handlers/HandleGetter.java
index fe3b86a4..c9d67d7f 100644
--- a/src/core/lombok/javac/handlers/HandleGetter.java
+++ b/src/core/lombok/javac/handlers/HandleGetter.java
@@ -30,6 +30,7 @@ import java.util.HashMap;
import java.util.Map;
import lombok.AccessLevel;
+import lombok.Delegate;
import lombok.Getter;
import lombok.core.AnnotationValues;
import lombok.core.TransformationsUtil;
@@ -240,16 +241,42 @@ public class HandleGetter extends JavacAnnotationHandler<Getter> {
List<JCAnnotation> nonNulls = findAnnotations(field, TransformationsUtil.NON_NULL_PATTERN);
List<JCAnnotation> nullables = findAnnotations(field, TransformationsUtil.NULLABLE_PATTERN);
+ List<JCAnnotation> delegates = findDelegatesAndRemoveFromField(field);
+
List<JCAnnotation> annsOnMethod = nonNulls.appendList(nullables);
JCMethodDecl decl = recursiveSetGeneratedBy(treeMaker.MethodDef(treeMaker.Modifiers(access, annsOnMethod), methodName, methodType,
methodGenericParams, parameters, throwsClauses, methodBody, annotationMethodDefaultValue), source);
if (toClearOfMarkers != null) recursiveSetGeneratedBy(toClearOfMarkers, null);
+ decl.mods.annotations = decl.mods.annotations.appendList(delegates);
return decl;
}
+ private static List<JCAnnotation> findDelegatesAndRemoveFromField(JavacNode field) {
+ JCVariableDecl fieldNode = (JCVariableDecl) field.get();
+
+ List<JCAnnotation> delegates = List.nil();
+ for (JCAnnotation annotation : fieldNode.mods.annotations) {
+ if (typeMatches(Delegate.class, field, annotation.annotationType)) {
+ delegates = delegates.append(annotation);
+ }
+ }
+
+ if (!delegates.isEmpty()) {
+ ListBuffer<JCAnnotation> withoutDelegates = ListBuffer.lb();
+ for (JCAnnotation annotation : fieldNode.mods.annotations) {
+ if (!delegates.contains(annotation)) {
+ withoutDelegates.append(annotation);
+ }
+ }
+ fieldNode.mods.annotations = withoutDelegates.toList();
+ field.rebuild();
+ }
+ return delegates;
+ }
+
private List<JCStatement> createSimpleGetterBody(TreeMaker treeMaker, JavacNode field) {
return List.<JCStatement>of(treeMaker.Return(createFieldAccessor(treeMaker, field, FieldAccess.ALWAYS_FIELD)));
}
diff --git a/src/eclipseAgent/lombok/eclipse/agent/PatchDelegate.java b/src/eclipseAgent/lombok/eclipse/agent/PatchDelegate.java
index 31ec52f4..87335b4e 100644
--- a/src/eclipseAgent/lombok/eclipse/agent/PatchDelegate.java
+++ b/src/eclipseAgent/lombok/eclipse/agent/PatchDelegate.java
@@ -188,6 +188,10 @@ public class PatchDelegate {
private static Map<ASTNode, Object> alreadyApplied = new WeakHashMap<ASTNode, Object>();
private static final Object MARKER = new Object();
+ public static void markHandled(Annotation annotation) {
+ alreadyApplied.put(annotation, MARKER);
+ }
+
private static void fillMethodBindingsForFields(CompilationUnitDeclaration cud, ClassScope scope, List<BindingTuple> methodsToDelegate) {
TypeDeclaration decl = scope.referenceContext;
if (decl == null) return;
diff --git a/src/utils/lombok/eclipse/Eclipse.java b/src/utils/lombok/eclipse/Eclipse.java
index fce0773b..7d21faa2 100644
--- a/src/utils/lombok/eclipse/Eclipse.java
+++ b/src/utils/lombok/eclipse/Eclipse.java
@@ -43,6 +43,7 @@ import org.eclipse.jdt.internal.compiler.ast.TypeReference;
import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
public class Eclipse {
+ private static final Annotation[] EMPTY_ANNOTATIONS_ARRAY = new Annotation[0];
/**
* Eclipse's Parser class is instrumented to not attempt to fill in the body of any method or initializer
* or field initialization if this flag is set. Set it on the flag field of
@@ -120,7 +121,7 @@ public class Eclipse {
*/
public static Annotation[] findAnnotations(FieldDeclaration field, Pattern namePattern) {
List<Annotation> result = new ArrayList<Annotation>();
- if (field.annotations == null) return new Annotation[0];
+ if (field.annotations == null) return EMPTY_ANNOTATIONS_ARRAY;
for (Annotation annotation : field.annotations) {
TypeReference typeRef = annotation.type;
if (typeRef != null && typeRef.getTypeName()!= null) {
@@ -131,7 +132,7 @@ public class Eclipse {
}
}
}
- return result.toArray(new Annotation[0]);
+ return result.toArray(EMPTY_ANNOTATIONS_ARRAY);
}
/**
diff --git a/test/transform/resource/after-delombok/DelegateOnGetter.java b/test/transform/resource/after-delombok/DelegateOnGetter.java
new file mode 100644
index 00000000..ee34018a
--- /dev/null
+++ b/test/transform/resource/after-delombok/DelegateOnGetter.java
@@ -0,0 +1,35 @@
+class DelegateOnGetter {
+ private final java.util.concurrent.atomic.AtomicReference<java.util.concurrent.atomic.AtomicReference<Bar>> bar = new java.util.concurrent.atomic.AtomicReference<java.util.concurrent.atomic.AtomicReference<Bar>>();
+ private interface Bar {
+ void setList(java.util.ArrayList<java.lang.String> list);
+ int getInt();
+ }
+ @java.lang.SuppressWarnings("all")
+ public Bar getBar() {
+ java.util.concurrent.atomic.AtomicReference<Bar> value = this.bar.get();
+ if (value == null) {
+ synchronized (this.bar) {
+ value = this.bar.get();
+ if (value == null) {
+ value = new java.util.concurrent.atomic.AtomicReference<Bar>(new Bar(){
+ public void setList(java.util.ArrayList<String> list) {
+ }
+ public int getInt() {
+ return 42;
+ }
+ });
+ this.bar.set(value);
+ }
+ }
+ }
+ return value.get();
+ }
+ @java.lang.SuppressWarnings("all")
+ public void setList(final java.util.ArrayList<java.lang.String> list) {
+ this.getBar().setList(list);
+ }
+ @java.lang.SuppressWarnings("all")
+ public int getInt() {
+ return this.getBar().getInt();
+ }
+} \ No newline at end of file
diff --git a/test/transform/resource/after-ecj/DelegateOnGetter.java b/test/transform/resource/after-ecj/DelegateOnGetter.java
new file mode 100644
index 00000000..cb06d3c1
--- /dev/null
+++ b/test/transform/resource/after-ecj/DelegateOnGetter.java
@@ -0,0 +1 @@
+//ignore \ No newline at end of file
diff --git a/test/transform/resource/after-eclipse/DelegateOnGetter.java b/test/transform/resource/after-eclipse/DelegateOnGetter.java
new file mode 100644
index 00000000..7d5907e0
--- /dev/null
+++ b/test/transform/resource/after-eclipse/DelegateOnGetter.java
@@ -0,0 +1,40 @@
+import lombok.Delegate;
+import lombok.Getter;
+class DelegateOnGetter {
+ private interface Bar {
+ void setList(java.util.ArrayList<java.lang.String> list);
+ int getInt();
+ }
+ private final @Delegate @Getter(lazy = true) java.util.concurrent.atomic.AtomicReference<java.util.concurrent.atomic.AtomicReference<Bar>> bar = new java.util.concurrent.atomic.AtomicReference<java.util.concurrent.atomic.AtomicReference<Bar>>();
+ public @Delegate @java.lang.SuppressWarnings("all") Bar getBar() {
+ java.util.concurrent.atomic.AtomicReference<Bar> value = this.bar.get();
+ if ((value == null))
+ {
+ synchronized (this.bar)
+ {
+ value = this.bar.get();
+ if ((value == null))
+ {
+ value = new java.util.concurrent.atomic.AtomicReference<Bar>(new Bar() {
+ public void setList(java.util.ArrayList<String> list) {
+ }
+ public int getInt() {
+ return 42;
+ }
+});
+ this.bar.set(value);
+ }
+ }
+ }
+ return value.get();
+ }
+ public @java.lang.SuppressWarnings("all") int getInt() {
+ return this.getBar().getInt();
+ }
+ public @java.lang.SuppressWarnings("all") void setList(final java.util.ArrayList<java.lang.String> list) {
+ this.getBar().setList(list);
+ }
+ DelegateOnGetter() {
+ super();
+ }
+} \ No newline at end of file
diff --git a/test/transform/resource/before/DelegateOnGetter.java b/test/transform/resource/before/DelegateOnGetter.java
new file mode 100644
index 00000000..afe09ff4
--- /dev/null
+++ b/test/transform/resource/before/DelegateOnGetter.java
@@ -0,0 +1,18 @@
+import lombok.Delegate;
+import lombok.Getter;
+
+class DelegateOnGetter {
+
+ @Delegate @Getter(lazy=true) private final Bar bar = new Bar() {
+ public void setList(java.util.ArrayList<String> list) {
+ }
+ public int getInt() {
+ return 42;
+ }
+ };
+
+ private interface Bar {
+ void setList(java.util.ArrayList<java.lang.String> list);
+ int getInt();
+ }
+} \ No newline at end of file