aboutsummaryrefslogtreecommitdiff
path: root/src/core/lombok/javac
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/javac
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/javac')
-rw-r--r--src/core/lombok/javac/HandlerLibrary.java30
-rw-r--r--src/core/lombok/javac/Javac.java44
-rw-r--r--src/core/lombok/javac/JavacAnnotationHandler.java6
-rw-r--r--src/core/lombok/javac/JavacTransformer.java22
-rw-r--r--src/core/lombok/javac/handlers/HandleCleanup.java24
-rw-r--r--src/core/lombok/javac/handlers/HandleConstructor.java54
-rw-r--r--src/core/lombok/javac/handlers/HandleData.java14
-rw-r--r--src/core/lombok/javac/handlers/HandleDelegate.java17
-rw-r--r--src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java49
-rw-r--r--src/core/lombok/javac/handlers/HandleGetter.java86
-rw-r--r--src/core/lombok/javac/handlers/HandleLog.java42
-rw-r--r--src/core/lombok/javac/handlers/HandlePrintAST.java6
-rw-r--r--src/core/lombok/javac/handlers/HandleSetter.java56
-rw-r--r--src/core/lombok/javac/handlers/HandleSneakyThrows.java31
-rw-r--r--src/core/lombok/javac/handlers/HandleSynchronized.java25
-rw-r--r--src/core/lombok/javac/handlers/HandleToString.java31
-rw-r--r--src/core/lombok/javac/handlers/HandleVal.java12
-rw-r--r--src/core/lombok/javac/handlers/JavacHandlerUtil.java30
18 files changed, 302 insertions, 277 deletions
diff --git a/src/core/lombok/javac/HandlerLibrary.java b/src/core/lombok/javac/HandlerLibrary.java
index 12a5a370..0c753c02 100644
--- a/src/core/lombok/javac/HandlerLibrary.java
+++ b/src/core/lombok/javac/HandlerLibrary.java
@@ -1,5 +1,5 @@
/*
- * Copyright © 2009-2010 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
@@ -27,6 +27,7 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
+import java.util.WeakHashMap;
import javax.annotation.processing.Messager;
import javax.tools.Diagnostic;
@@ -37,6 +38,7 @@ import lombok.core.TypeLibrary;
import lombok.core.TypeResolver;
import lombok.core.AnnotationValues.AnnotationValueDecodeFail;
+import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.JCTree.JCAnnotation;
import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
@@ -74,8 +76,8 @@ public class HandlerLibrary {
return handler.isResolutionBased();
}
- public boolean handle(final JavacNode node) {
- return handler.handle(Javac.createAnnotation(annotationClass, node), (JCAnnotation)node.get(), node);
+ public void handle(final JavacNode node) {
+ handler.handle(Javac.createAnnotation(annotationClass, node), (JCAnnotation)node.get(), node);
}
}
@@ -141,6 +143,15 @@ public class HandlerLibrary {
if (t != null) t.printStackTrace();
}
+ private static final Map<JCTree, Object> handledMap = new WeakHashMap<JCTree, Object>();
+ private static final Object MARKER = new Object();
+
+ private boolean checkAndSetHandled(JCTree node) {
+ synchronized (handledMap) {
+ return handledMap.put(node, MARKER) != MARKER;
+ }
+ }
+
/**
* Handles the provided annotation node by first finding a qualifying instance of
* {@link JavacAnnotationHandler} and if one exists, calling it with a freshly cooked up
@@ -158,10 +169,11 @@ public class HandlerLibrary {
* @param node The Lombok AST Node representing the Annotation AST Node.
* @param annotation 'node.get()' - convenience parameter.
*/
- public boolean handleAnnotation(JCCompilationUnit unit, JavacNode node, JCAnnotation annotation) {
+ public void handleAnnotation(JCCompilationUnit unit, JavacNode node, JCAnnotation annotation) {
+ if (!checkAndSetHandled(annotation)) return;
+
TypeResolver resolver = new TypeResolver(typeLibrary, node.getPackageDeclaration(), node.getImportStatements());
String rawType = annotation.annotationType.toString();
- boolean handled = false;
for (String fqn : resolver.findTypeMatches(node, rawType)) {
boolean isPrintAST = fqn.equals(PrintAST.class.getName());
if (isPrintAST && phase != 2) continue;
@@ -170,9 +182,9 @@ public class HandlerLibrary {
if (container == null) continue;
try {
- if (container.isResolutionBased() && phase == 1) handled |= container.handle(node);
- if (!container.isResolutionBased() && phase == 0) handled |= container.handle(node);
- if (container.annotationClass == PrintAST.class && phase == 2) handled |= container.handle(node);
+ if (container.isResolutionBased() && phase == 1) container.handle(node);
+ if (!container.isResolutionBased() && phase == 0) container.handle(node);
+ if (container.annotationClass == PrintAST.class && phase == 2) container.handle(node);
} catch (AnnotationValueDecodeFail fail) {
fail.owner.setError(fail.getMessage(), fail.idx);
} catch (Throwable t) {
@@ -181,8 +193,6 @@ public class HandlerLibrary {
javacError(String.format("Lombok annotation handler %s failed on " + sourceName, container.handler.getClass()), t);
}
}
-
- return handled;
}
/**
diff --git a/src/core/lombok/javac/Javac.java b/src/core/lombok/javac/Javac.java
index 8eb56e1d..64e8ee27 100644
--- a/src/core/lombok/javac/Javac.java
+++ b/src/core/lombok/javac/Javac.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.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.WeakHashMap;
import lombok.Lombok;
import lombok.core.AST.Kind;
@@ -45,6 +46,7 @@ import com.sun.tools.javac.tree.JCTree.JCFieldAccess;
import com.sun.tools.javac.tree.JCTree.JCIdent;
import com.sun.tools.javac.tree.JCTree.JCLiteral;
import com.sun.tools.javac.tree.JCTree.JCNewArray;
+import com.sun.tools.javac.tree.TreeScanner;
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
/**
@@ -194,4 +196,44 @@ public class Javac {
throw Lombok.sneakyThrow(e);
}
}
+
+ private static class MarkingScanner extends TreeScanner {
+ private final JCTree source;
+
+ MarkingScanner(JCTree source) {
+ this.source = source;
+ }
+
+ @Override public void scan(JCTree tree) {
+ setGeneratedBy(tree, source);
+ super.scan(tree);
+ }
+ }
+
+ private static Map<JCTree, JCTree> generatedNodes = new WeakHashMap<JCTree, JCTree>();
+
+ public static JCTree getGeneratedBy(JCTree node) {
+ synchronized (generatedNodes) {
+ return generatedNodes.get(node);
+ }
+ }
+
+ public static boolean isGenerated(JCTree node) {
+ return getGeneratedBy(node) != null;
+ }
+
+ public static <T extends JCTree> T recursiveSetGeneratedBy(T node, JCTree source) {
+ setGeneratedBy(node, source);
+ node.accept(new MarkingScanner(source));
+
+ return node;
+ }
+
+ public static <T extends JCTree> T setGeneratedBy(T node, JCTree source) {
+ synchronized (generatedNodes) {
+ if (source == null) generatedNodes.remove(node);
+ else generatedNodes.put(node, source);
+ }
+ return node;
+ }
}
diff --git a/src/core/lombok/javac/JavacAnnotationHandler.java b/src/core/lombok/javac/JavacAnnotationHandler.java
index ee330ecb..3e9f6660 100644
--- a/src/core/lombok/javac/JavacAnnotationHandler.java
+++ b/src/core/lombok/javac/JavacAnnotationHandler.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
@@ -51,10 +51,8 @@ public interface JavacAnnotationHandler<T extends Annotation> {
* @param annotationNode The Lombok AST wrapper around the 'ast' parameter. You can use this object
* to travel back up the chain (something javac AST can't do) to the parent of the annotation, as well
* as access useful methods such as generating warnings or errors focused on the annotation.
- * @return {@code true} if you don't want to be called again about this annotation during this
- * compile session (you've handled it), or {@code false} to indicate you aren't done yet.
*/
- boolean handle(AnnotationValues<T> annotation, JCAnnotation ast, JavacNode annotationNode);
+ void handle(AnnotationValues<T> annotation, JCAnnotation ast, JavacNode annotationNode);
/**
* Return true if this handler requires resolution.
diff --git a/src/core/lombok/javac/JavacTransformer.java b/src/core/lombok/javac/JavacTransformer.java
index beef6924..7423d061 100644
--- a/src/core/lombok/javac/JavacTransformer.java
+++ b/src/core/lombok/javac/JavacTransformer.java
@@ -1,5 +1,5 @@
/*
- * Copyright © 2009-2010 Reinier Zwitserloot, Roel Spilker and Robbert Jan Grootjans.
+ * Copyright © 2009-2011 Reinier Zwitserloot, Roel Spilker and Robbert Jan Grootjans.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -88,38 +88,28 @@ public class JavacTransformer {
private class AnnotationVisitor extends JavacASTAdapter {
@Override public void visitAnnotationOnType(JCClassDecl type, JavacNode annotationNode, JCAnnotation annotation) {
- if (annotationNode.isHandled()) return;
JCCompilationUnit top = (JCCompilationUnit) annotationNode.top().get();
- boolean handled = handlers.handleAnnotation(top, annotationNode, annotation);
- if (handled) annotationNode.setHandled();
+ handlers.handleAnnotation(top, annotationNode, annotation);
}
@Override public void visitAnnotationOnField(JCVariableDecl field, JavacNode annotationNode, JCAnnotation annotation) {
- if (annotationNode.isHandled()) return;
JCCompilationUnit top = (JCCompilationUnit) annotationNode.top().get();
- boolean handled = handlers.handleAnnotation(top, annotationNode, annotation);
- if (handled) annotationNode.setHandled();
+ handlers.handleAnnotation(top, annotationNode, annotation);
}
@Override public void visitAnnotationOnMethod(JCMethodDecl method, JavacNode annotationNode, JCAnnotation annotation) {
- if (annotationNode.isHandled()) return;
JCCompilationUnit top = (JCCompilationUnit) annotationNode.top().get();
- boolean handled = handlers.handleAnnotation(top, annotationNode, annotation);
- if (handled) annotationNode.setHandled();
+ handlers.handleAnnotation(top, annotationNode, annotation);
}
@Override public void visitAnnotationOnMethodArgument(JCVariableDecl argument, JCMethodDecl method, JavacNode annotationNode, JCAnnotation annotation) {
- if (annotationNode.isHandled()) return;
JCCompilationUnit top = (JCCompilationUnit) annotationNode.top().get();
- boolean handled = handlers.handleAnnotation(top, annotationNode, annotation);
- if (handled) annotationNode.setHandled();
+ handlers.handleAnnotation(top, annotationNode, annotation);
}
@Override public void visitAnnotationOnLocal(JCVariableDecl local, JavacNode annotationNode, JCAnnotation annotation) {
- if (annotationNode.isHandled()) return;
JCCompilationUnit top = (JCCompilationUnit) annotationNode.top().get();
- boolean handled = handlers.handleAnnotation(top, annotationNode, annotation);
- if (handled) annotationNode.setHandled();
+ handlers.handleAnnotation(top, annotationNode, annotation);
}
}
}
diff --git a/src/core/lombok/javac/handlers/HandleCleanup.java b/src/core/lombok/javac/handlers/HandleCleanup.java
index b681ab28..eb4b7987 100644
--- a/src/core/lombok/javac/handlers/HandleCleanup.java
+++ b/src/core/lombok/javac/handlers/HandleCleanup.java
@@ -1,5 +1,5 @@
/*
- * Copyright © 2009-2010 Reinier Zwitserloot, Roel Spilker and Robbert Jan Grootjans.
+ * Copyright © 2009-2011 Reinier Zwitserloot, Roel Spilker and Robbert Jan Grootjans.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -21,7 +21,7 @@
*/
package lombok.javac.handlers;
-import static lombok.javac.handlers.JavacHandlerUtil.markAnnotationAsProcessed;
+import static lombok.javac.handlers.JavacHandlerUtil.deleteAnnotationIfNeccessary;
import lombok.Cleanup;
import lombok.core.AnnotationValues;
import lombok.core.AST.Kind;
@@ -59,24 +59,24 @@ import com.sun.tools.javac.util.Name;
*/
@ProviderFor(JavacAnnotationHandler.class)
public class HandleCleanup implements JavacAnnotationHandler<Cleanup> {
- @Override public boolean handle(AnnotationValues<Cleanup> annotation, JCAnnotation ast, JavacNode annotationNode) {
- markAnnotationAsProcessed(annotationNode, Cleanup.class);
+ @Override public void handle(AnnotationValues<Cleanup> annotation, JCAnnotation ast, JavacNode annotationNode) {
+ deleteAnnotationIfNeccessary(annotationNode, Cleanup.class);
String cleanupName = annotation.getInstance().value();
if (cleanupName.length() == 0) {
annotationNode.addError("cleanupName cannot be the empty string.");
- return true;
+ return;
}
if (annotationNode.up().getKind() != Kind.LOCAL) {
annotationNode.addError("@Cleanup is legal only on local variable declarations.");
- return true;
+ return;
}
JCVariableDecl decl = (JCVariableDecl)annotationNode.up().get();
if (decl.init == null) {
annotationNode.addError("@Cleanup variable declarations need to be initialized.");
- return true;
+ return;
}
JavacNode ancestor = annotationNode.up().directUp();
@@ -91,7 +91,7 @@ public class HandleCleanup implements JavacAnnotationHandler<Cleanup> {
statements = ((JCMethodDecl)blockNode).body.stats;
} else {
annotationNode.addError("@Cleanup is legal only on a local variable declaration inside a block.");
- return true;
+ return;
}
boolean seenDeclaration = false;
@@ -108,7 +108,7 @@ public class HandleCleanup implements JavacAnnotationHandler<Cleanup> {
if (!seenDeclaration) {
annotationNode.addError("LOMBOK BUG: Can't find this local variable declaration inside its parent.");
- return true;
+ return;
}
doAssignmentCheck(annotationNode, tryBlock.toList(), decl.name);
@@ -122,9 +122,9 @@ public class HandleCleanup implements JavacAnnotationHandler<Cleanup> {
JCIf ifNotNullCleanup = maker.If(isNull, maker.Block(0, cleanupCall), null);
- JCBlock finalizer = maker.Block(0, List.<JCStatement>of(ifNotNullCleanup));
+ JCBlock finalizer = Javac.recursiveSetGeneratedBy(maker.Block(0, List.<JCStatement>of(ifNotNullCleanup)), ast);
- newStatements.append(maker.Try(maker.Block(0, tryBlock.toList()), List.<JCCatch>nil(), finalizer));
+ newStatements.append(Javac.setGeneratedBy(maker.Try(Javac.setGeneratedBy(maker.Block(0, tryBlock.toList()), ast), List.<JCCatch>nil(), finalizer), ast));
if (blockNode instanceof JCBlock) {
((JCBlock)blockNode).stats = newStatements.toList();
@@ -135,8 +135,6 @@ public class HandleCleanup implements JavacAnnotationHandler<Cleanup> {
} else throw new AssertionError("Should not get here");
ancestor.rebuild();
-
- return true;
}
private JCMethodInvocation preventNullAnalysis(TreeMaker maker, JavacNode node, JCExpression expression) {
diff --git a/src/core/lombok/javac/handlers/HandleConstructor.java b/src/core/lombok/javac/handlers/HandleConstructor.java
index 1497b1b4..fd7d5a9d 100644
--- a/src/core/lombok/javac/handlers/HandleConstructor.java
+++ b/src/core/lombok/javac/handlers/HandleConstructor.java
@@ -37,6 +37,7 @@ import lombok.javac.handlers.JavacHandlerUtil.MemberExistsResult;
import org.mangosdk.spi.ProviderFor;
import com.sun.tools.javac.code.Flags;
+import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.TreeMaker;
import com.sun.tools.javac.tree.JCTree.JCAnnotation;
import com.sun.tools.javac.tree.JCTree.JCAssign;
@@ -58,19 +59,18 @@ import com.sun.tools.javac.util.ListBuffer;
public class HandleConstructor {
@ProviderFor(JavacAnnotationHandler.class)
public static class HandleNoArgsConstructor implements JavacAnnotationHandler<NoArgsConstructor> {
- @Override public boolean handle(AnnotationValues<NoArgsConstructor> annotation, JCAnnotation ast, JavacNode annotationNode) {
- markAnnotationAsProcessed(annotationNode, NoArgsConstructor.class);
+ @Override public void handle(AnnotationValues<NoArgsConstructor> annotation, JCAnnotation ast, JavacNode annotationNode) {
+ deleteAnnotationIfNeccessary(annotationNode, NoArgsConstructor.class);
deleteImportFromCompilationUnit(annotationNode, "lombok.AccessLevel");
JavacNode typeNode = annotationNode.up();
- if (!checkLegality(typeNode, annotationNode, NoArgsConstructor.class.getSimpleName())) return true;
+ if (!checkLegality(typeNode, annotationNode, NoArgsConstructor.class.getSimpleName())) return;
NoArgsConstructor ann = annotation.getInstance();
AccessLevel level = ann.access();
String staticName = ann.staticName();
- if (level == AccessLevel.NONE) return true;
+ if (level == AccessLevel.NONE) return;
List<JavacNode> fields = List.nil();
List<JCExpression> onConstructor = getAndRemoveAnnotationParameter(ast, "onConstructor");
- new HandleConstructor().generateConstructor(typeNode, level, fields, staticName, onConstructor, false, false);
- return true;
+ new HandleConstructor().generateConstructor(typeNode, level, fields, staticName, onConstructor, false, false, annotationNode);
}
@Override public boolean isResolutionBased() {
@@ -80,20 +80,19 @@ public class HandleConstructor {
@ProviderFor(JavacAnnotationHandler.class)
public static class HandleRequiredArgsConstructor implements JavacAnnotationHandler<RequiredArgsConstructor> {
- @Override public boolean handle(AnnotationValues<RequiredArgsConstructor> annotation, JCAnnotation ast, JavacNode annotationNode) {
- markAnnotationAsProcessed(annotationNode, RequiredArgsConstructor.class);
+ @Override public void handle(AnnotationValues<RequiredArgsConstructor> annotation, JCAnnotation ast, JavacNode annotationNode) {
+ deleteAnnotationIfNeccessary(annotationNode, RequiredArgsConstructor.class);
deleteImportFromCompilationUnit(annotationNode, "lombok.AccessLevel");
JavacNode typeNode = annotationNode.up();
- if (!checkLegality(typeNode, annotationNode, RequiredArgsConstructor.class.getSimpleName())) return true;
+ if (!checkLegality(typeNode, annotationNode, RequiredArgsConstructor.class.getSimpleName())) return;
RequiredArgsConstructor ann = annotation.getInstance();
AccessLevel level = ann.access();
String staticName = ann.staticName();
@SuppressWarnings("deprecation")
boolean suppressConstructorProperties = ann.suppressConstructorProperties();
- if (level == AccessLevel.NONE) return true;
+ if (level == AccessLevel.NONE) return;
List<JCExpression> onConstructor = getAndRemoveAnnotationParameter(ast, "onConstructor");
- new HandleConstructor().generateConstructor(typeNode, level, findRequiredFields(typeNode), staticName, onConstructor, false, suppressConstructorProperties);
- return true;
+ new HandleConstructor().generateConstructor(typeNode, level, findRequiredFields(typeNode), staticName, onConstructor, false, suppressConstructorProperties, annotationNode);
}
@Override public boolean isResolutionBased() {
@@ -120,17 +119,17 @@ public class HandleConstructor {
@ProviderFor(JavacAnnotationHandler.class)
public static class HandleAllArgsConstructor implements JavacAnnotationHandler<AllArgsConstructor> {
- @Override public boolean handle(AnnotationValues<AllArgsConstructor> annotation, JCAnnotation ast, JavacNode annotationNode) {
- markAnnotationAsProcessed(annotationNode, AllArgsConstructor.class);
+ @Override public void handle(AnnotationValues<AllArgsConstructor> annotation, JCAnnotation ast, JavacNode annotationNode) {
+ deleteAnnotationIfNeccessary(annotationNode, AllArgsConstructor.class);
deleteImportFromCompilationUnit(annotationNode, "lombok.AccessLevel");
JavacNode typeNode = annotationNode.up();
- if (!checkLegality(typeNode, annotationNode, AllArgsConstructor.class.getSimpleName())) return true;
+ if (!checkLegality(typeNode, annotationNode, AllArgsConstructor.class.getSimpleName())) return;
AllArgsConstructor ann = annotation.getInstance();
AccessLevel level = ann.access();
String staticName = ann.staticName();
@SuppressWarnings("deprecation")
boolean suppressConstructorProperties = ann.suppressConstructorProperties();
- if (level == AccessLevel.NONE) return true;
+ if (level == AccessLevel.NONE) return;
ListBuffer<JavacNode> fields = ListBuffer.lb();
for (JavacNode child : typeNode.down()) {
if (child.getKind() != Kind.FIELD) continue;
@@ -145,8 +144,7 @@ public class HandleConstructor {
fields.append(child);
}
List<JCExpression> onConstructor = getAndRemoveAnnotationParameter(ast, "onConstructor");
- new HandleConstructor().generateConstructor(typeNode, level, fields.toList(), staticName, onConstructor, false, suppressConstructorProperties);
- return true;
+ new HandleConstructor().generateConstructor(typeNode, level, fields.toList(), staticName, onConstructor, false, suppressConstructorProperties, annotationNode);
}
@Override public boolean isResolutionBased() {
@@ -168,11 +166,11 @@ public class HandleConstructor {
return true;
}
- public void generateRequiredArgsConstructor(JavacNode typeNode, AccessLevel level, String staticName, boolean skipIfConstructorExists) {
- generateConstructor(typeNode, level, findRequiredFields(typeNode), staticName, List.<JCExpression>nil(), skipIfConstructorExists, false);
+ public void generateRequiredArgsConstructor(JavacNode typeNode, AccessLevel level, String staticName, boolean skipIfConstructorExists, JavacNode source) {
+ generateConstructor(typeNode, level, findRequiredFields(typeNode), staticName, List.<JCExpression>nil(), skipIfConstructorExists, false, source);
}
- public void generateConstructor(JavacNode typeNode, AccessLevel level, List<JavacNode> fields, String staticName, List<JCExpression> onConstructor, boolean skipIfConstructorExists, boolean suppressConstructorProperties) {
+ public void generateConstructor(JavacNode typeNode, AccessLevel level, List<JavacNode> fields, String staticName, List<JCExpression> onConstructor, boolean skipIfConstructorExists, boolean suppressConstructorProperties, JavacNode source) {
if (skipIfConstructorExists && constructorExists(typeNode) != MemberExistsResult.NOT_EXISTS) return;
if (skipIfConstructorExists) {
for (JavacNode child : typeNode.down()) {
@@ -187,10 +185,10 @@ public class HandleConstructor {
boolean staticConstrRequired = staticName != null && !staticName.equals("");
- JCMethodDecl constr = createConstructor(staticConstrRequired ? AccessLevel.PRIVATE : level, typeNode, fields, onConstructor, suppressConstructorProperties);
+ JCMethodDecl constr = createConstructor(staticConstrRequired ? AccessLevel.PRIVATE : level, typeNode, fields, onConstructor, suppressConstructorProperties, source.get());
injectMethod(typeNode, constr);
if (staticConstrRequired) {
- JCMethodDecl staticConstr = createStaticConstructor(staticName, level, typeNode, fields);
+ JCMethodDecl staticConstr = createStaticConstructor(staticName, level, typeNode, fields, source.get());
injectMethod(typeNode, staticConstr);
}
}
@@ -208,7 +206,7 @@ public class HandleConstructor {
mods.annotations = mods.annotations.append(annotation);
}
- private JCMethodDecl createConstructor(AccessLevel level, JavacNode typeNode, List<JavacNode> fields, List<JCExpression> onConstructor, boolean suppressConstructorProperties) {
+ private JCMethodDecl createConstructor(AccessLevel level, JavacNode typeNode, List<JavacNode> fields, List<JCExpression> onConstructor, boolean suppressConstructorProperties, JCTree source) {
TreeMaker maker = typeNode.getTreeMaker();
boolean isEnum = (((JCClassDecl) typeNode.get()).mods.flags & Flags.ENUM) != 0;
@@ -239,8 +237,8 @@ public class HandleConstructor {
if (!suppressConstructorProperties && level != AccessLevel.PRIVATE && !isLocalType(typeNode)) {
addConstructorProperties(mods, typeNode, fields);
}
- return maker.MethodDef(mods, typeNode.toName("<init>"),
- null, List.<JCTypeParameter>nil(), params.toList(), List.<JCExpression>nil(), maker.Block(0L, nullChecks.appendList(assigns).toList()), null);
+ return Javac.recursiveSetGeneratedBy(maker.MethodDef(mods, typeNode.toName("<init>"),
+ null, List.<JCTypeParameter>nil(), params.toList(), List.<JCExpression>nil(), maker.Block(0L, nullChecks.appendList(assigns).toList()), null), source);
}
private boolean isLocalType(JavacNode type) {
@@ -250,7 +248,7 @@ public class HandleConstructor {
return true;
}
- private JCMethodDecl createStaticConstructor(String name, AccessLevel level, JavacNode typeNode, List<JavacNode> fields) {
+ private JCMethodDecl createStaticConstructor(String name, AccessLevel level, JavacNode typeNode, List<JavacNode> fields, JCTree source) {
TreeMaker maker = typeNode.getTreeMaker();
JCClassDecl type = (JCClassDecl) typeNode.get();
@@ -298,6 +296,6 @@ public class HandleConstructor {
JCReturn returnStatement = maker.Return(maker.NewClass(null, List.<JCExpression>nil(), constructorType, args.toList(), null));
JCBlock body = maker.Block(0, List.<JCStatement>of(returnStatement));
- return maker.MethodDef(mods, typeNode.toName(name), returnType, typeParams.toList(), params.toList(), List.<JCExpression>nil(), body, null);
+ return Javac.recursiveSetGeneratedBy(maker.MethodDef(mods, typeNode.toName(name), returnType, typeParams.toList(), params.toList(), List.<JCExpression>nil(), body, null), source);
}
}
diff --git a/src/core/lombok/javac/handlers/HandleData.java b/src/core/lombok/javac/handlers/HandleData.java
index 682b7fe4..b0490b35 100644
--- a/src/core/lombok/javac/handlers/HandleData.java
+++ b/src/core/lombok/javac/handlers/HandleData.java
@@ -1,5 +1,5 @@
/*
- * Copyright © 2009-2010 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
@@ -21,7 +21,7 @@
*/
package lombok.javac.handlers;
-import static lombok.javac.handlers.JavacHandlerUtil.markAnnotationAsProcessed;
+import static lombok.javac.handlers.JavacHandlerUtil.deleteAnnotationIfNeccessary;
import lombok.AccessLevel;
import lombok.Data;
import lombok.core.AnnotationValues;
@@ -39,8 +39,8 @@ import com.sun.tools.javac.tree.JCTree.JCClassDecl;
*/
@ProviderFor(JavacAnnotationHandler.class)
public class HandleData implements JavacAnnotationHandler<Data> {
- @Override public boolean handle(AnnotationValues<Data> annotation, JCAnnotation ast, JavacNode annotationNode) {
- markAnnotationAsProcessed(annotationNode, Data.class);
+ @Override public void handle(AnnotationValues<Data> annotation, JCAnnotation ast, JavacNode annotationNode) {
+ deleteAnnotationIfNeccessary(annotationNode, Data.class);
JavacNode typeNode = annotationNode.up();
JCClassDecl typeDecl = null;
if (typeNode.get() instanceof JCClassDecl) typeDecl = (JCClassDecl)typeNode.get();
@@ -49,19 +49,17 @@ public class HandleData implements JavacAnnotationHandler<Data> {
if (typeDecl == null || notAClass) {
annotationNode.addError("@Data is only supported on a class.");
- return false;
+ return;
}
String staticConstructorName = annotation.getInstance().staticConstructor();
// TODO move this to the end OR move it to the top in eclipse.
- new HandleConstructor().generateRequiredArgsConstructor(typeNode, AccessLevel.PUBLIC, staticConstructorName, true);
+ new HandleConstructor().generateRequiredArgsConstructor(typeNode, AccessLevel.PUBLIC, staticConstructorName, true, annotationNode);
new HandleGetter().generateGetterForType(typeNode, annotationNode, AccessLevel.PUBLIC, true);
new HandleSetter().generateSetterForType(typeNode, annotationNode, AccessLevel.PUBLIC, true);
new HandleEqualsAndHashCode().generateEqualsAndHashCodeForType(typeNode, annotationNode);
new HandleToString().generateToStringForType(typeNode, annotationNode);
-
- return true;
}
@Override public boolean isResolutionBased() {
diff --git a/src/core/lombok/javac/handlers/HandleDelegate.java b/src/core/lombok/javac/handlers/HandleDelegate.java
index e333daa3..f1d872ae 100644
--- a/src/core/lombok/javac/handlers/HandleDelegate.java
+++ b/src/core/lombok/javac/handlers/HandleDelegate.java
@@ -21,7 +21,7 @@
*/
package lombok.javac.handlers;
-import static lombok.javac.handlers.JavacHandlerUtil.markAnnotationAsProcessed;
+import static lombok.javac.handlers.JavacHandlerUtil.deleteAnnotationIfNeccessary;
import java.util.ArrayList;
import java.util.Arrays;
@@ -43,6 +43,7 @@ import lombok.Delegate;
import lombok.core.AST.Kind;
import lombok.core.AnnotationValues;
import lombok.javac.FindTypeVarScanner;
+import lombok.javac.Javac;
import lombok.javac.JavacAnnotationHandler;
import lombok.javac.JavacNode;
import lombok.javac.JavacResolution;
@@ -91,11 +92,11 @@ public class HandleDelegate implements JavacAnnotationHandler<Delegate> {
"clone()",
"finalize()"));
- @Override public boolean handle(AnnotationValues<Delegate> annotation, JCAnnotation ast, JavacNode annotationNode) {
- markAnnotationAsProcessed(annotationNode, Delegate.class);
+ @Override public void handle(AnnotationValues<Delegate> annotation, JCAnnotation ast, JavacNode annotationNode) {
+ deleteAnnotationIfNeccessary(annotationNode, Delegate.class);
if (annotationNode.up().getKind() != Kind.FIELD) {
// As the annotation is legal on fields only, javac itself will take care of printing an error message for this.
- return false;
+ return;
}
List<Object> delegateTypes = annotation.getActualExpressions("types");
@@ -148,7 +149,7 @@ public class HandleDelegate implements JavacAnnotationHandler<Delegate> {
addMethodBindings(signaturesToExclude, ct, annotationNode, banList);
} else {
annotationNode.addError("@Delegate can only use concrete class types, not wildcards, arrays, type variables, or primitives.");
- return false;
+ return;
}
}
@@ -162,15 +163,13 @@ public class HandleDelegate implements JavacAnnotationHandler<Delegate> {
addMethodBindings(signaturesToDelegate, ct, annotationNode, banList);
} else {
annotationNode.addError("@Delegate can only use concrete class types, not wildcards, arrays, type variables, or primitives.");
- return false;
+ return;
}
}
Name delegateFieldName = annotationNode.toName(annotationNode.up().getName());
for (MethodSig sig : signaturesToDelegate) generateAndAdd(sig, annotationNode, delegateFieldName);
-
- return false;
}
private void generateAndAdd(MethodSig sig, JavacNode annotation, Name delegateFieldName) {
@@ -295,7 +294,7 @@ public class HandleDelegate implements JavacAnnotationHandler<Delegate> {
JCStatement body = useReturn ? maker.Return(delegateCall) : maker.Exec(delegateCall);
JCBlock bodyBlock = maker.Block(0, com.sun.tools.javac.util.List.of(body));
- return maker.MethodDef(mods, sig.name, returnType, toList(typeParams), toList(params), toList(thrown), bodyBlock, null);
+ return Javac.recursiveSetGeneratedBy(maker.MethodDef(mods, sig.name, returnType, toList(typeParams), toList(params), toList(thrown), bodyBlock, null), annotation.get());
}
private static <T> com.sun.tools.javac.util.List<T> toList(ListBuffer<T> collection) {
diff --git a/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java b/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java
index 78ecbd9c..1172e3ab 100644
--- a/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java
+++ b/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java
@@ -1,5 +1,5 @@
/*
- * Copyright © 2009-2010 Reinier Zwitserloot, Roel Spilker and Robbert Jan Grootjans.
+ * Copyright © 2009-2011 Reinier Zwitserloot, Roel Spilker and Robbert Jan Grootjans.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -72,8 +72,8 @@ public class HandleEqualsAndHashCode implements JavacAnnotationHandler<EqualsAnd
}
}
- @Override public boolean handle(AnnotationValues<EqualsAndHashCode> annotation, JCAnnotation ast, JavacNode annotationNode) {
- markAnnotationAsProcessed(annotationNode, EqualsAndHashCode.class);
+ @Override public void handle(AnnotationValues<EqualsAndHashCode> annotation, JCAnnotation ast, JavacNode annotationNode) {
+ deleteAnnotationIfNeccessary(annotationNode, EqualsAndHashCode.class);
EqualsAndHashCode ann = annotation.getInstance();
List<String> excludes = List.from(ann.exclude());
List<String> includes = List.from(ann.of());
@@ -93,10 +93,10 @@ public class HandleEqualsAndHashCode implements JavacAnn