aboutsummaryrefslogtreecommitdiff
path: root/src/core/lombok/eclipse/HandlerLibrary.java
diff options
context:
space:
mode:
authorReinier Zwitserloot <reinier@zwitserloot.com>2011-05-30 22:04:46 +0200
committerReinier Zwitserloot <reinier@zwitserloot.com>2011-05-30 22:08:12 +0200
commitaa8a627349bb68f376b98847b6f73c2c89e989fd (patch)
tree70df1fa6ba0f8e3c34a45d868d7f763e5b7ccbf9 /src/core/lombok/eclipse/HandlerLibrary.java
parentdaf84dd00ed5059710acf9f40b4663ba7fed06e0 (diff)
downloadlombok-aa8a627349bb68f376b98847b6f73c2c89e989fd.tar.gz
lombok-aa8a627349bb68f376b98847b6f73c2c89e989fd.tar.bz2
lombok-aa8a627349bb68f376b98847b6f73c2c89e989fd.zip
tracking if an annotation has been handled or not is now no longer done
via the LombokAST object. Instead its tracked more directly in an attempt to avoid having to write all handlers as idempotent, and just in case issue #164 is a race condition (the handled-or-not is a synchronized CAS check). This does break API for other plugins, but the fix is trivial: Just make your 'handle' method return void. That 'we won't call you again' business in the decks never quite worked right anyway. Also, you might want to call Javac.(recursive)setHandledBy when you generate nodes, now.
Diffstat (limited to 'src/core/lombok/eclipse/HandlerLibrary.java')
-rw-r--r--src/core/lombok/eclipse/HandlerLibrary.java29
1 files changed, 19 insertions, 10 deletions
diff --git a/src/core/lombok/eclipse/HandlerLibrary.java b/src/core/lombok/eclipse/HandlerLibrary.java
index ba7f891a..109f6fe1 100644
--- a/src/core/lombok/eclipse/HandlerLibrary.java
+++ b/src/core/lombok/eclipse/HandlerLibrary.java
@@ -1,5 +1,5 @@
/*
- * Copyright © 2009 Reinier Zwitserloot and Roel Spilker.
+ * Copyright © 2009-2011 Reinier Zwitserloot and Roel Spilker.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -29,6 +29,7 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
+import java.util.WeakHashMap;
import lombok.Lombok;
import lombok.core.AnnotationValues;
@@ -38,6 +39,7 @@ import lombok.core.TypeLibrary;
import lombok.core.TypeResolver;
import lombok.core.AnnotationValues.AnnotationValueDecodeFail;
+import org.eclipse.jdt.internal.compiler.ast.ASTNode;
import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
import org.eclipse.jdt.internal.compiler.ast.TypeReference;
@@ -65,10 +67,10 @@ public class HandlerLibrary {
this.annotationClass = annotationClass;
}
- public boolean handle(org.eclipse.jdt.internal.compiler.ast.Annotation annotation,
+ public void handle(org.eclipse.jdt.internal.compiler.ast.Annotation annotation,
final EclipseNode annotationNode) {
AnnotationValues<T> annValues = Eclipse.createAnnotation(annotationClass, annotationNode);
- return handler.handle(annValues, annotation, annotationNode);
+ handler.handle(annValues, annotation, annotationNode);
}
}
@@ -126,6 +128,15 @@ public class HandlerLibrary {
}
}
+ private static final Map<ASTNode, Object> handledMap = new WeakHashMap<ASTNode, Object>();
+ private static final Object MARKER = new Object();
+
+ private boolean checkAndSetHandled(ASTNode node) {
+ synchronized (handledMap) {
+ return handledMap.put(node, MARKER) != 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
@@ -143,15 +154,15 @@ public class HandlerLibrary {
* @param annotationNode The Lombok AST Node representing the Annotation AST Node.
* @param annotation 'node.get()' - convenience parameter.
*/
- public boolean handle(CompilationUnitDeclaration ast, EclipseNode annotationNode,
- org.eclipse.jdt.internal.compiler.ast.Annotation annotation) {
+ public void handleAnnotation(CompilationUnitDeclaration ast, EclipseNode annotationNode, org.eclipse.jdt.internal.compiler.ast.Annotation annotation) {
+ if (!checkAndSetHandled(annotation)) return;
+
String pkgName = annotationNode.getPackageDeclaration();
Collection<String> imports = annotationNode.getImportStatements();
TypeResolver resolver = new TypeResolver(typeLibrary, pkgName, imports);
TypeReference rawType = annotation.type;
- if (rawType == null) return false;
- boolean handled = false;
+ if (rawType == null) return;
for (String fqn : resolver.findTypeMatches(annotationNode, toQualifiedName(annotation.type.getTypeName()))) {
boolean isPrintAST = fqn.equals(PrintAST.class.getName());
if (isPrintAST == skipPrintAST) continue;
@@ -160,15 +171,13 @@ public class HandlerLibrary {
if (container == null) continue;
try {
- handled |= container.handle(annotation, annotationNode);
+ container.handle(annotation, annotationNode);
} catch (AnnotationValueDecodeFail fail) {
fail.owner.setError(fail.getMessage(), fail.idx);
} catch (Throwable t) {
Eclipse.error(ast, String.format("Lombok annotation handler %s failed", container.handler.getClass()), t);
}
}
-
- return handled;
}
/**