aboutsummaryrefslogtreecommitdiff
path: root/src/core/lombok/javac/HandlerLibrary.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/lombok/javac/HandlerLibrary.java')
-rw-r--r--src/core/lombok/javac/HandlerLibrary.java94
1 files changed, 51 insertions, 43 deletions
diff --git a/src/core/lombok/javac/HandlerLibrary.java b/src/core/lombok/javac/HandlerLibrary.java
index 9666c9d5..1ce083f3 100644
--- a/src/core/lombok/javac/HandlerLibrary.java
+++ b/src/core/lombok/javac/HandlerLibrary.java
@@ -25,14 +25,17 @@ import java.io.IOException;
import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
+import java.util.SortedSet;
+import java.util.TreeSet;
import java.util.WeakHashMap;
import javax.annotation.processing.Messager;
import javax.tools.Diagnostic;
-import lombok.core.PrintAST;
+import lombok.core.HandlerPriority;
import lombok.core.SpiLoadUtil;
import lombok.core.TypeLibrary;
import lombok.core.TypeResolver;
@@ -52,9 +55,8 @@ import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
public class HandlerLibrary {
private final TypeLibrary typeLibrary = new TypeLibrary();
private final Map<String, AnnotationHandlerContainer<?>> annotationHandlers = new HashMap<String, AnnotationHandlerContainer<?>>();
- private final Collection<JavacASTVisitor> visitorHandlers = new ArrayList<JavacASTVisitor>();
+ private final Collection<VisitorContainer> visitorHandlers = new ArrayList<VisitorContainer>();
private final Messager messager;
- private int phase = 0;
/**
* Creates a new HandlerLibrary that will report any problems or errors to the provided messager.
@@ -64,22 +66,53 @@ public class HandlerLibrary {
this.messager = messager;
}
+ private static class VisitorContainer {
+ private final JavacASTVisitor visitor;
+ private final long priority;
+
+ VisitorContainer(JavacASTVisitor visitor) {
+ this.visitor = visitor;
+ HandlerPriority hp = visitor.getClass().getAnnotation(HandlerPriority.class);
+ this.priority = hp == null ? 0L : (((long)hp.value()) << 32) + hp.subValue();
+ }
+
+ public long getPriority() {
+ return priority;
+ }
+ }
+
private static class AnnotationHandlerContainer<T extends Annotation> {
- private JavacAnnotationHandler<T> handler;
- private Class<T> annotationClass;
+ private final JavacAnnotationHandler<T> handler;
+ private final Class<T> annotationClass;
+ private final long priority;
AnnotationHandlerContainer(JavacAnnotationHandler<T> handler, Class<T> annotationClass) {
this.handler = handler;
this.annotationClass = annotationClass;
- }
-
- public boolean isResolutionBased() {
- return handler.getClass().isAnnotationPresent(ResolutionBased.class);
+ HandlerPriority hp = handler.getClass().getAnnotation(HandlerPriority.class);
+ this.priority = hp == null ? 0L : (((long)hp.value()) << 32) + hp.subValue();
}
public void handle(final JavacNode node) {
handler.handle(JavacHandlerUtil.createAnnotation(annotationClass, node), (JCAnnotation)node.get(), node);
}
+
+ public long getPriority() {
+ return priority;
+ }
+ }
+
+ private SortedSet<Long> priorities;
+
+ public SortedSet<Long> getPriorities() {
+ return priorities;
+ }
+
+ private void calculatePriorities() {
+ SortedSet<Long> set = new TreeSet<Long>();
+ for (AnnotationHandlerContainer<?> container : annotationHandlers.values()) set.add(container.getPriority());
+ for (VisitorContainer container : visitorHandlers) set.add(container.getPriority());
+ this.priorities = Collections.unmodifiableSortedSet(set);
}
/**
@@ -97,6 +130,8 @@ public class HandlerLibrary {
System.err.println("Lombok isn't running due to misconfigured SPI files: " + e);
}
+ library.calculatePriorities();
+
return library;
}
@@ -120,7 +155,7 @@ public class HandlerLibrary {
private static void loadVisitorHandlers(HandlerLibrary lib) throws IOException {
//No, that seemingly superfluous reference to JavacASTVisitor's classloader is not in fact superfluous!
for (JavacASTVisitor visitor : SpiLoadUtil.findServices(JavacASTVisitor.class, JavacASTVisitor.class.getClassLoader())) {
- lib.visitorHandlers.add(visitor);
+ lib.visitorHandlers.add(new VisitorContainer(visitor));
}
}
@@ -171,24 +206,15 @@ public class HandlerLibrary {
* @param node The Lombok AST Node representing the Annotation AST Node.
* @param annotation 'node.get()' - convenience parameter.
*/
- public void handleAnnotation(JCCompilationUnit unit, JavacNode node, JCAnnotation annotation) {
+ public void handleAnnotation(JCCompilationUnit unit, JavacNode node, JCAnnotation annotation, long priority) {
TypeResolver resolver = new TypeResolver(node.getPackageDeclaration(), node.getImportStatements());
String rawType = annotation.annotationType.toString();
for (String fqn : resolver.findTypeMatches(node, typeLibrary, rawType)) {
- boolean isPrintAST = fqn.equals(PrintAST.class.getName());
- if (isPrintAST && phase != 2) continue;
- if (!isPrintAST && phase == 2) continue;
AnnotationHandlerContainer<?> container = annotationHandlers.get(fqn);
if (container == null) continue;
try {
- if (container.isResolutionBased() && phase == 1) {
- if (checkAndSetHandled(annotation)) container.handle(node);
- }
- if (!container.isResolutionBased() && phase == 0) {
- if (checkAndSetHandled(annotation)) container.handle(node);
- }
- if (container.annotationClass == PrintAST.class && phase == 2) {
+ if (container.getPriority() == priority) {
if (checkAndSetHandled(annotation)) container.handle(node);
}
} catch (AnnotationValueDecodeFail fail) {
@@ -204,29 +230,11 @@ public class HandlerLibrary {
/**
* Will call all registered {@link JavacASTVisitor} instances.
*/
- public void callASTVisitors(JavacAST ast) {
- for (JavacASTVisitor visitor : visitorHandlers) try {
- boolean isResolutionBased = visitor.getClass().isAnnotationPresent(ResolutionBased.class);
- if (!isResolutionBased && phase == 0) ast.traverse(visitor);
- if (isResolutionBased && phase == 1) ast.traverse(visitor);
+ public void callASTVisitors(JavacAST ast, long priority) {
+ for (VisitorContainer container : visitorHandlers) try {
+ if (container.getPriority() == priority) ast.traverse(container.visitor);
} catch (Throwable t) {
- javacError(String.format("Lombok visitor handler %s failed", visitor.getClass()), t);
+ javacError(String.format("Lombok visitor handler %s failed", container.visitor.getClass()), t);
}
}
-
- /**
- * Lombok does not currently support triggering annotations in a specified order; the order is essentially
- * random right now. As a temporary hack we've identified 3 important phases.
- */
- public void setPreResolutionPhase() {
- phase = 0;
- }
-
- public void setPostResolutionPhase() {
- phase = 1;
- }
-
- public void setPrintASTPhase() {
- phase = 2;
- }
}