aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/lombok/eclipse/EclipseAnnotationHandler.java10
-rw-r--r--src/core/lombok/eclipse/HandlerLibrary.java17
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);