diff options
-rw-r--r-- | src/core/lombok/eclipse/EclipseAnnotationHandler.java | 10 | ||||
-rw-r--r-- | src/core/lombok/eclipse/HandlerLibrary.java | 17 |
2 files changed, 26 insertions, 1 deletions
diff --git a/src/core/lombok/eclipse/EclipseAnnotationHandler.java b/src/core/lombok/eclipse/EclipseAnnotationHandler.java index 10c0b6fb..aa8fbc2e 100644 --- a/src/core/lombok/eclipse/EclipseAnnotationHandler.java +++ b/src/core/lombok/eclipse/EclipseAnnotationHandler.java @@ -51,6 +51,16 @@ public abstract class EclipseAnnotationHandler<T extends java.lang.annotation.An public abstract void handle(AnnotationValues<T> annotation, org.eclipse.jdt.internal.compiler.ast.Annotation ast, EclipseNode annotationNode); /** + * Called when you want to defer until post diet, and we're still in pre-diet. May be called not at all or multiple times, so make sure + * this method is idempotent if run more than once, and whatever you do here should also be done in the main 'handle' method. + * + * NB: This method exists because in certain cases, within eclipse, you have to create i.e. a field before referencing it in generated code. You still + * have to create the field, if its not already there, in 'handle', because for example preHandle would never even be called in ecj mode. + */ + public void preHandle(AnnotationValues<T> annotation, org.eclipse.jdt.internal.compiler.ast.Annotation ast, EclipseNode annotationNode) { + } + + /** * Return true if this handler should not be run in the diet parse phase. * 'diet parse' is where method bodies aren't filled in yet. If you have a method-level annotation that modifies the contents of that method, * return {@code true} here. Otherwise, return {@code false} here. diff --git a/src/core/lombok/eclipse/HandlerLibrary.java b/src/core/lombok/eclipse/HandlerLibrary.java index efc00873..dc082a8d 100644 --- a/src/core/lombok/eclipse/HandlerLibrary.java +++ b/src/core/lombok/eclipse/HandlerLibrary.java @@ -73,6 +73,12 @@ public class HandlerLibrary { handler.handle(annValues, annotation, annotationNode); } + public void preHandle(org.eclipse.jdt.internal.compiler.ast.Annotation annotation, + final EclipseNode annotationNode) { + AnnotationValues<T> annValues = Eclipse.createAnnotation(annotationClass, annotationNode); + handler.preHandle(annValues, annotation, annotationNode); + } + public boolean deferUntilPostDiet() { return handler.deferUntilPostDiet(); } @@ -141,6 +147,12 @@ public class HandlerLibrary { } } + private boolean needsHandling(ASTNode node) { + synchronized (handledMap) { + return handledMap.get(node) != MARKER; + } + } + /** * Handles the provided annotation node by first finding a qualifying instance of * {@link EclipseAnnotationHandler} and if one exists, calling it with a freshly cooked up @@ -171,7 +183,10 @@ public class HandlerLibrary { AnnotationHandlerContainer<?> container = annotationHandlers.get(fqn); if (container == null) continue; - if (!annotationNode.isCompleteParse() && container.deferUntilPostDiet()) continue; + if (!annotationNode.isCompleteParse() && container.deferUntilPostDiet()) { + if (needsHandling(annotation)) container.preHandle(annotation, annotationNode); + continue; + } try { if (checkAndSetHandled(annotation)) container.handle(annotation, annotationNode); |