diff options
author | Reinier Zwitserloot <reinier@zwitserloot.com> | 2011-05-30 22:04:46 +0200 |
---|---|---|
committer | Reinier Zwitserloot <reinier@zwitserloot.com> | 2011-05-30 22:08:12 +0200 |
commit | aa8a627349bb68f376b98847b6f73c2c89e989fd (patch) | |
tree | 70df1fa6ba0f8e3c34a45d868d7f763e5b7ccbf9 /src/core/lombok | |
parent | daf84dd00ed5059710acf9f40b4663ba7fed06e0 (diff) | |
download | lombok-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')
34 files changed, 433 insertions, 530 deletions
diff --git a/src/core/lombok/core/LombokNode.java b/src/core/lombok/core/LombokNode.java index 90e55757..4989f304 100644 --- a/src/core/lombok/core/LombokNode.java +++ b/src/core/lombok/core/LombokNode.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 @@ -45,13 +45,6 @@ public abstract class LombokNode<A extends AST<A, L, N>, L extends LombokNode<A, protected final List<L> children; protected L parent; - /** This flag has no specified meaning; you can set and retrieve it. - * - * In practice, for annotation nodes it means: Some AnnotationHandler finished whatever changes were required, - * and for all other nodes it means: This node was made by a lombok operation. - */ - protected boolean handled; - /** structurally significant are those nodes that can be annotated in java 1.6 or are method-like toplevels, * so fields, local declarations, method arguments, methods, types, the Compilation Unit itself, and initializers. */ protected boolean isStructurallySignificant; @@ -84,8 +77,8 @@ public abstract class LombokNode<A extends AST<A, L, N>, L extends LombokNode<A, /** {@inheritDoc} */ @Override public String toString() { - return String.format("NODE %s (%s) %s%s", - kind, node == null ? "(NULL)" : node.getClass(), handled ? "[HANDLED]" : "", node == null ? "" : node); + return String.format("NODE %s (%s) %s", + kind, node == null ? "(NULL)" : node.getClass(), node == null ? "" : node); } /** @@ -220,26 +213,6 @@ public abstract class LombokNode<A extends AST<A, L, N>, L extends LombokNode<A, } /** - * returns the value of the 'handled' flag. - * - * @see #handled - */ - public boolean isHandled() { - return handled; - } - - /** - * Sets the handled flag, then returns itself for chaining. - * - * @see #handled - */ - @SuppressWarnings("unchecked") - public L setHandled() { - this.handled = true; - return (L)this; - } - - /** * Convenient shortcut to the owning ast object's top method. * * @see AST#top() @@ -309,18 +282,6 @@ public abstract class LombokNode<A extends AST<A, L, N>, L extends LombokNode<A, } /** - * Sets the handled flag on this node, and all child nodes, then returns itself, for chaining. - * - * @see #handled - */ - @SuppressWarnings("unchecked") - public L recursiveSetHandled() { - this.handled = true; - for (L child : children) child.recursiveSetHandled(); - return (L) this; - } - - /** * Structurally significant means: LocalDeclaration, TypeDeclaration, MethodDeclaration, ConstructorDeclaration, * FieldDeclaration, Initializer, and CompilationUnitDeclaration. * The rest is e.g. if statements, while loops, etc. diff --git a/src/core/lombok/eclipse/EclipseAnnotationHandler.java b/src/core/lombok/eclipse/EclipseAnnotationHandler.java index aaa57603..c105f252 100644 --- a/src/core/lombok/eclipse/EclipseAnnotationHandler.java +++ b/src/core/lombok/eclipse/EclipseAnnotationHandler.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 @@ -47,8 +47,6 @@ public interface EclipseAnnotationHandler<T extends java.lang.annotation.Annotat * @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, org.eclipse.jdt.internal.compiler.ast.Annotation ast, EclipseNode annotationNode); + void handle(AnnotationValues<T> annotation, org.eclipse.jdt.internal.compiler.ast.Annotation ast, EclipseNode annotationNode); } 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; } /** diff --git a/src/core/lombok/eclipse/TransformEclipseAST.java b/src/core/lombok/eclipse/TransformEclipseAST.java index aada3ca4..314c8a7d 100644 --- a/src/core/lombok/eclipse/TransformEclipseAST.java +++ b/src/core/lombok/eclipse/TransformEclipseAST.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 @@ -168,38 +168,28 @@ public class TransformEclipseAST { private static class AnnotationVisitor extends EclipseASTAdapter { @Override public void visitAnnotationOnField(FieldDeclaration field, EclipseNode annotationNode, Annotation annotation) { - if (annotationNode.isHandled()) return; CompilationUnitDeclaration top = (CompilationUnitDeclaration) annotationNode.top().get(); - boolean handled = handlers.handle(top, annotationNode, annotation); - if (handled) annotationNode.setHandled(); + handlers.handleAnnotation(top, annotationNode, annotation); } @Override public void visitAnnotationOnMethodArgument(Argument arg, AbstractMethodDeclaration method, EclipseNode annotationNode, Annotation annotation) { - if (annotationNode.isHandled()) return; CompilationUnitDeclaration top = (CompilationUnitDeclaration) annotationNode.top().get(); - boolean handled = handlers.handle(top, annotationNode, annotation); - if (handled) annotationNode.setHandled(); + handlers.handleAnnotation(top, annotationNode, annotation); } @Override public void visitAnnotationOnLocal(LocalDeclaration local, EclipseNode annotationNode, Annotation annotation) { - if (annotationNode.isHandled()) return; CompilationUnitDeclaration top = (CompilationUnitDeclaration) annotationNode.top().get(); - boolean handled = handlers.handle(top, annotationNode, annotation); - if (handled) annotationNode.setHandled(); + handlers.handleAnnotation(top, annotationNode, annotation); } @Override public void visitAnnotationOnMethod(AbstractMethodDeclaration method, EclipseNode annotationNode, Annotation annotation) { - if (annotationNode.isHandled()) return; CompilationUnitDeclaration top = (CompilationUnitDeclaration) annotationNode.top().get(); - boolean handled = handlers.handle(top, annotationNode, annotation); - if (handled) annotationNode.setHandled(); + handlers.handleAnnotation(top, annotationNode, annotation); } @Override public void visitAnnotationOnType(TypeDeclaration type, EclipseNode annotationNode, Annotation annotation) { - if (annotationNode.isHandled()) return; CompilationUnitDeclaration top = (CompilationUnitDeclaration) annotationNode.top().get(); - boolean handled = handlers.handle(top, annotationNode, annotation); - if (handled) annotationNode.setHandled(); + handlers.handleAnnotation(top, annotationNode, annotation); } } } diff --git a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java index d16e3ead..0eae12f2 100644 --- a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java +++ b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.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 @@ -332,9 +332,7 @@ public class EclipseHandlerUtil { char[] fName = def.name; if (fName == null) continue; if (fieldName.equals(new String(fName))) { - EclipseNode existing = node.getNodeFor(def); - if (existing == null || !existing.isHandled()) return MemberExistsResult.EXISTS_BY_USER; - return MemberExistsResult.EXISTS_BY_LOMBOK; + return Eclipse.getGeneratedBy(def) == null ? MemberExistsResult.EXISTS_BY_USER : MemberExistsResult.EXISTS_BY_LOMBOK; } } } @@ -369,11 +367,7 @@ public class EclipseHandlerUtil { char[] mName = def.selector; if (mName == null) continue; boolean nameEquals = caseSensitive ? methodName.equals(new String(mName)) : methodName.equalsIgnoreCase(new String(mName)); - if (nameEquals) { - EclipseNode existing = node.getNodeFor(def); - if (existing == null || !existing.isHandled()) return MemberExistsResult.EXISTS_BY_USER; - return MemberExistsResult.EXISTS_BY_LOMBOK; - } + if (nameEquals) return Eclipse.getGeneratedBy(def) == null ? MemberExistsResult.EXISTS_BY_USER : MemberExistsResult.EXISTS_BY_LOMBOK; } } } @@ -397,9 +391,7 @@ public class EclipseHandlerUtil { if (typeDecl.methods != null) for (AbstractMethodDeclaration def : typeDecl.methods) { if (def instanceof ConstructorDeclaration) { if ((def.bits & ASTNode.IsDefaultConstructor) != 0) continue; - EclipseNode existing = node.getNodeFor(def); - if (existing == null || !existing.isHandled()) return MemberExistsResult.EXISTS_BY_USER; - return MemberExistsResult.EXISTS_BY_LOMBOK; + return Eclipse.getGeneratedBy(def) == null ? MemberExistsResult.EXISTS_BY_USER : MemberExistsResult.EXISTS_BY_LOMBOK; } } } @@ -408,55 +400,6 @@ public class EclipseHandlerUtil { } /** - * Returns the constructor that's already been generated by lombok. - * Provide any node that represents the type (TypeDeclaration) to look in, or any child node thereof. - */ - public static EclipseNode getExistingLombokConstructor(EclipseNode node) { - while (node != null && !(node.get() instanceof TypeDeclaration)) { - node = node.up(); - } - - if (node == null) return null; - - if (node.get() instanceof TypeDeclaration) { - for (AbstractMethodDeclaration def : ((TypeDeclaration)node.get()).methods) { - if (def instanceof ConstructorDeclaration) { - if ((def.bits & ASTNode.IsDefaultConstructor) != 0) continue; - EclipseNode existing = node.getNodeFor(def); - if (existing.isHandled()) return existing; - } - } - } - - return null; - } - - /** - * Returns the method that's already been generated by lombok with the given name. - * Provide any node that represents the type (TypeDeclaration) to look in, or any child node thereof. - */ - public static EclipseNode getExistingLombokMethod(String methodName, EclipseNode node) { - while (node != null && !(node.get() instanceof TypeDeclaration)) { - node = node.up(); - } - - if (node == null) return null; - - if (node.get() instanceof TypeDeclaration) { - for (AbstractMethodDeclaration def : ((TypeDeclaration)node.get()).methods) { - char[] mName = def.selector; - if (mName == null) continue; - if (methodName.equals(new String(mName))) { - EclipseNode existing = node.getNodeFor(def); - if (existing.isHandled()) return existing; - } - } - } - - return null; - } - - /** * Inserts a field into an existing type. The type must represent a {@code TypeDeclaration}. * The field carries the @{@link SuppressWarnings}("all") annotation. */ @@ -487,7 +430,7 @@ public class EclipseHandlerUtil { } } - type.add(field, Kind.FIELD).recursiveSetHandled(); + type.add(field, Kind.FIELD); } private static boolean hasClinit(TypeDeclaration parent) { @@ -573,7 +516,7 @@ public class EclipseHandlerUtil { parent.methods = newArray; } - type.add(method, Kind.METHOD).recursiveSetHandled(); + type.add(method, Kind.METHOD); } private static final char[] ALL = "all".toCharArray(); diff --git a/src/core/lombok/eclipse/handlers/HandleCleanup.java b/src/core/lombok/eclipse/handlers/HandleCleanup.java index 9a63ce47..4f9615b6 100644 --- a/src/core/lombok/eclipse/handlers/HandleCleanup.java +++ b/src/core/lombok/eclipse/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 @@ -59,23 +59,23 @@ import org.mangosdk.spi.ProviderFor; */ @ProviderFor(EclipseAnnotationHandler.class) public class HandleCleanup implements EclipseAnnotationHandler<Cleanup> { - public boolean handle(AnnotationValues<Cleanup> annotation, Annotation ast, EclipseNode annotationNode) { + public void handle(AnnotationValues<Cleanup> annotation, Annotation ast, EclipseNode annotationNode) { 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; } LocalDeclaration decl = (LocalDeclaration)annotationNode.up().get(); if (decl.initialization == null) { annotationNode.addError("@Cleanup variable declarations need to be initialized."); - return true; + return; } EclipseNode ancestor = annotationNode.up().directUp(); @@ -94,12 +94,12 @@ public class HandleCleanup implements EclipseAnnotationHandler<Cleanup> { statements = ((SwitchStatement)blockNode).statements; } else { annotationNode.addError("@Cleanup is legal only on a local variable declaration inside a block."); - return true; + return; } if (statements == null) { annotationNode.addError("LOMBOK BUG: Parent block does not contain any statements."); - return true; + return; } int start = 0; @@ -109,7 +109,7 @@ public class HandleCleanup implements EclipseAnnotationHandler<Cleanup> { if (start == statements.length) { annotationNode.addError("LOMBOK BUG: Can't find this local variable declaration inside its parent."); - return true; + return; } start++; //We start with try{} *AFTER* the var declaration. @@ -205,8 +205,6 @@ public class HandleCleanup implements EclipseAnnotationHandler<Cleanup> { } ancestor.rebuild(); - - return true; } private MessageSend preventNullAnalysis(Annotation ast, Expression expr) { diff --git a/src/core/lombok/eclipse/handlers/HandleConstructor.java b/src/core/lombok/eclipse/handlers/HandleConstructor.java index db26beed..e0715961 100644 --- a/src/core/lombok/eclipse/handlers/HandleConstructor.java +++ b/src/core/lombok/eclipse/handlers/HandleConstructor.java @@ -73,34 +73,32 @@ import org.mangosdk.spi.ProviderFor; public class HandleConstructor { @ProviderFor(EclipseAnnotationHandler.class) public static class HandleNoArgsConstructor implements EclipseAnnotationHandler<NoArgsConstructor> { - @Override public boolean handle(AnnotationValues<NoArgsConstructor> annotation, Annotation ast, EclipseNode annotationNode) { + @Override public void handle(AnnotationValues<NoArgsConstructor> annotation, Annotation ast, EclipseNode annotationNode) { EclipseNode 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<EclipseNode> fields = new ArrayList<EclipseNode>(); Annotation[] onConstructor = getAndRemoveAnnotationParameter(ast, "onConstructor"); new HandleConstructor().generateConstructor(typeNode, level, fields, staticName, onConstructor, false, false, ast); - return true; } } @ProviderFor(EclipseAnnotationHandler.class) public static class HandleRequiredArgsConstructor implements EclipseAnnotationHandler<RequiredArgsConstructor> { - @Override public boolean handle(AnnotationValues<RequiredArgsConstructor> annotation, Annotation ast, EclipseNode annotationNode) { + @Override public void handle(AnnotationValues<RequiredArgsConstructor> annotation, Annotation ast, EclipseNode annotationNode) { EclipseNode 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; Annotation[] onConstructor = getAndRemoveAnnotationParameter(ast, "onConstructor"); new HandleConstructor().generateConstructor(typeNode, level, findRequiredFields(typeNode), staticName, onConstructor, false, suppressConstructorProperties, ast); - return true; } } @@ -119,15 +117,15 @@ public class HandleConstructor { @ProviderFor(EclipseAnnotationHandler.class) public static class HandleAllArgsConstructor implements EclipseAnnotationHandler<AllArgsConstructor> { - @Override public boolean handle(AnnotationValues<AllArgsConstructor> annotation, Annotation ast, EclipseNode annotationNode) { + @Override public void handle(AnnotationValues<AllArgsConstructor> annotation, Annotation ast, EclipseNode annotationNode) { EclipseNode 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; List<EclipseNode> fields = new ArrayList<EclipseNode>(); for (EclipseNode child : typeNode.down()) { if (child.getKind() != Kind.FIELD) continue; @@ -135,13 +133,12 @@ public class HandleConstructor { if (!EclipseHandlerUtil.filterField(fieldDecl)) continue; // Skip initialized final fields. - if (((fieldDecl.modifiers & ClassFileConstants.AccFinal) != 0) && fieldDecl.initialization != null) return false; + if (((fieldDecl.modifiers & ClassFileConstants.AccFinal) != 0) && fieldDecl.initialization != null) return; fields.add(child); } Annotation[] onConstructor = getAndRemoveAnnotationParameter(ast, "onConstructor"); new HandleConstructor().generateConstructor(typeNode, level, fields, staticName, onConstructor, false, suppressConstructorProperties, ast); - return true; } } diff --git a/src/core/lombok/eclipse/handlers/HandleData.java b/src/core/lombok/eclipse/handlers/HandleData.java index 0a28ccf4..9b3d7e51 100644 --- a/src/core/lombok/eclipse/handlers/HandleData.java +++ b/src/core/lombok/eclipse/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 @@ -37,7 +37,7 @@ import org.mangosdk.spi.ProviderFor; */ @ProviderFor(EclipseAnnotationHandler.class) public class HandleData implements EclipseAnnotationHandler<Data> { - public boolean handle(AnnotationValues<Data> annotation, Annotation ast, EclipseNode annotationNode) { + public void handle(AnnotationValues<Data> annotation, Annotation ast, EclipseNode annotationNode) { Data ann = annotation.getInstance(); EclipseNode typeNode = annotationNode.up(); @@ -49,7 +49,7 @@ public class HandleData implements EclipseAnnotationHandler<Data> { if (typeDecl == null || notAClass) { annotationNode.addError("@Data is only supported on a class."); - return false; + return; } //Careful: Generate the public static constructor (if there is one) LAST, so that any attempt to @@ -63,7 +63,5 @@ public class HandleData implements EclipseAnnotationHandler<Data> { new HandleEqualsAndHashCode().generateEqualsAndHashCodeForType(typeNode, annotationNode); new HandleToString().generateToStringForType(typeNode, annotationNode); new HandleConstructor().generateRequiredArgsConstructor(typeNode, AccessLevel.PUBLIC, ann.staticConstructor(), true, ast); - - return false; } } diff --git a/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java b/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java index 8ee7272c..3be8fdfa 100644 --- a/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java +++ b/src/core/lombok/eclipse/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 @@ -116,7 +116,7 @@ public class HandleEqualsAndHashCode implements EclipseAnnotationHandler<EqualsA generateMethods(typeNode, errorNode, null, null, null, false, FieldAccess.GETTER); } - @Override public boolean handle(AnnotationValues<EqualsAndHashCode> annotation, + @Override public void handle(AnnotationValues<EqualsAndHashCode> annotation, Annotation ast, EclipseNode annotationNode) { EqualsAndHashCode ann = annotation.getInstance(); List<String> excludes = Arrays.asList(ann.exclude()); @@ -137,10 +137,10 @@ public class HandleEqualsAndHashCode implements EclipseAnnotationHandler<EqualsA FieldAccess fieldAccess = ann.doNotUseGetters() ? FieldAccess.PREFER_FIELD : FieldAccess.GETTER; - return generateMethods(typeNode, annotationNode, excludes, includes, callSuper, true, fieldAccess); + generateMethods(typeNode, annotationNode, excludes, includes, callSuper, true, fieldAccess); } - public boolean generateMethods(EclipseNode typeNode, EclipseNode errorNode, List<String> excludes, List<String> includes, + public void generateMethods(EclipseNode typeNode, EclipseNode errorNode, List<String> excludes, List<String> includes, Boolean callSuper, boolean whineIfExists, FieldAccess fieldAccess) { assert excludes == null || includes == null; @@ -153,7 +153,7 @@ public class HandleEqualsAndHashCode implements EclipseAnnotationHandler<EqualsA if (typeDecl == null || notAClass) { errorNode.addError("@EqualsAndHashCode is only supported on a class."); - return false; + return; } boolean implicitCallSuper = callSuper == null; @@ -175,7 +175,7 @@ public class HandleEqualsAndHashCode implements EclipseAnnotationHandler<EqualsA if (isDirectDescendantOfObject && callSuper) { errorNode.addError("Generating equals/hashCode with a supercall to java.lang.Object is pointless."); - return true; + return; } if (!isDirectDescendantOfObject && !callSuper && implicitCallSuper) { @@ -249,8 +249,6 @@ public class HandleEqualsAndHashCode implements EclipseAnnotationHandler<EqualsA } break; } - - return true; } private MethodDeclaration createHashCode(EclipseNode type, Collection<EclipseNode> fields, boolean callSuper, ASTNode source, FieldAccess fieldAccess) { diff --git a/src/core/lombok/eclipse/handlers/HandleGetter.java b/src/core/lombok/eclipse/handlers/HandleGetter.java index f39e55b5..3af09afb 100644 --- a/src/core/lombok/eclipse/handlers/HandleGetter.java +++ b/src/core/lombok/eclipse/handlers/HandleGetter.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 @@ -131,7 +131,7 @@ public class HandleGetter implements EclipseAnnotationHandler<Getter> { createGetterForField(level, fieldNode, fieldNode, pos, false, onMethod, lazy); } - public boolean handle(AnnotationValues<Getter> annotation, Annotation ast, EclipseNode annotationNode) { + public void handle(AnnotationValues<Getter> annotation, Annotation ast, EclipseNode annotationNode) { EclipseNode node = annotationNode.up(); Getter annotationInstance = annotation.getInstance(); AccessLevel level = annotationInstance.value(); @@ -140,46 +140,46 @@ public class HandleGetter implements EclipseAnnotationHandler<Getter> { if (lazy) { annotationNode.addWarning("'lazy' does not work with AccessLevel.NONE."); } - return true; + return; } - if (node == null) return false; + if (node == null) return; Annotation[] onMethod = getAndRemoveAnnotationParameter(ast, "onMethod"); - if (node.getKind() == Kind.FIELD) { - return createGetterForFields(level, annotationNode.upFromAnnotationToFields(), annotationNode, annotationNode.get(), true, onMethod, lazy); - } - if (node.getKind() == Kind.TYPE) { + switch (node.getKind()) { + case FIELD: + createGetterForFields(level, annotationNode.upFromAnnotationToFields(), annotationNode, annotationNode.get(), true, onMethod, lazy); + break; + case TYPE: if (onMethod != null && onMethod.length != 0) annotationNode.addError("'onMethod' is not supported for @Getter on a type."); if (lazy) annotationNode.addError("'lazy' is not supported for @Getter on a type."); - return generateGetterForType(node, annotationNode, level, false); + generateGetterForType(node, annotationNode, level, false); + break; } - return false; } - private boolean createGetterForFields(AccessLevel level, Collection<EclipseNode> fieldNodes, EclipseNode errorNode, ASTNode source, boolean whineIfExists, Annotation[] onMethod, boolean lazy) { + private void createGetterForFields(AccessLevel level, Collection<EclipseNode> fieldNodes, EclipseNode errorNode, ASTNode source, boolean whineIfExists, Annotation[] onMethod, boolean lazy) { for (EclipseNode fieldNode : fieldNodes) { createGetterForField(level, fieldNode, errorNode, source, whineIfExists, onMethod, lazy); } - return true; } - private boolean createGetterForField(AccessLevel level, + private void createGetterForField(AccessLevel level, EclipseNode fieldNode, EclipseNode errorNode, ASTNode source, boolean whineIfExists, Annotation[] onMethod, boolean lazy) { if (fieldNode.getKind() != Kind.FIELD) { errorNode.addError("@Getter is only supported on a class or a field."); - return true; + return; } FieldDeclaration field = (FieldDeclaration) fieldNode.get(); if (lazy) { if ((field.modifiers & ClassFileConstants.AccPrivate) == 0 || (field.modifiers & ClassFileConstants.AccFinal) == 0) { errorNode.addError("'lazy' requires the field to be private and final."); - return true; + return; } if (field.initialization == null) { errorNode.addError("'lazy' requires field initialization."); - return true; + return; } } @@ -193,7 +193,7 @@ public class HandleGetter implements EclipseAnnotationHandler<Getter> { for (String altName : TransformationsUtil.toAllGetterNames(fieldName, isBoolean)) { switch (methodExists(altName, fieldNode, false)) { case EXISTS_BY_LOMBOK: - return true; + return; case EXISTS_BY_USER: if (whineIfExists) { String altNameExpl = ""; @@ -201,7 +201,7 @@ public class HandleGetter implements EclipseAnnotationHandler<Getter> { errorNode.addWarning( String.format("Not generating %s(): A method with that name already exists%s", getterName, altNameExpl)); } - return true; + return; default: case NOT_EXISTS: //continue scanning the other alt names. @@ -215,8 +215,6 @@ public class HandleGetter implements EclipseAnnotationHandler<Getter> { } injectMethod(fieldNode.up(), method); - - return true; } private MethodDeclaration generateGetter(TypeDeclaration parent, EclipseNode fieldNode, String name, int modifier, ASTNode source, boolean lazy) { diff --git a/src/core/lombok/eclipse/handlers/HandleLog.java b/src/core/lombok/eclipse/handlers/HandleLog.java index be856208..a51d8e7e 100644 --- a/src/core/lombok/eclipse/handlers/HandleLog.java +++ b/src/core/lombok/eclipse/handlers/HandleLog.java @@ -51,7 +51,7 @@ public class HandleLog { throw new UnsupportedOperationException(); } - public static boolean processAnnotation(LoggingFramework framework, AnnotationValues<? extends java.lang.annotation.Annotation> annotation, Annotation source, EclipseNode annotationNode) { + public static void processAnnotation(LoggingFramework framework, AnnotationValues<? extends java.lang.annotation.Annotation> annotation, Annotation source, EclipseNode annotationNode) { EclipseNode owner = annotationNode.up(); switch (owner.getKind()) { case TYPE: @@ -64,22 +64,22 @@ public class HandleLog { if (typeDecl == null || notAClass) { annotationNode.addError("@Log is legal only on classes and enums."); - return false; + return; } if (fieldExists("log", owner) != MemberExistsResult.NOT_EXISTS) { annotationNode.addWarning("Field 'log' already exists."); - return true; + return; } ClassLiteralAccess loggingType = selfType(owner, source); injectField(owner, createField(framework, source, loggingType)); owner.rebuild(); - return true; + break; default: annotationNode.addError("@Log is legal only on types."); - return true; + break; } } @@ -154,8 +154,8 @@ public class HandleLog { */ @ProviderFor(EclipseAnnotationHandler.class) public static class HandleCommonsLog implements EclipseAnnotationHandler<lombok.extern.apachecommons.CommonsLog> { - @Override public boolean handle(AnnotationValues<lombok.extern.apachecommons.CommonsLog> annotation, Annotation source, EclipseNode annotationNode) { - return processAnnotation(LoggingFramework.COMMONS, annotation, source, annotationNode); + @Override public void handle(AnnotationValues<lombok.extern.apachecommons.CommonsLog> annotation, Annotation source, EclipseNode annotationNode) { + processAnnotation(LoggingFramework.COMMONS, annotation, source, annotationNode); } } @@ -164,8 +164,8 @@ public class HandleLog { */ @ProviderFor(EclipseAnnotationHandler.class) public static class HandleJulLog implements EclipseAnnotationHandler<lombok.extern.java.Log> { - @Override public boolean handle(AnnotationValues<lombok.extern.java.Log> annotation, Annotation source, EclipseNode annotationNode) { - return processAnnotation(LoggingFramework.JUL, annotation, source, annotationNode); + @Override public void handle(AnnotationValues<lombok.extern.java.Log> annotation, Annotation source, EclipseNode annotationNode) { + processAnnotation(LoggingFramework.JUL, annotation, source, annotationNode); } } @@ -174,8 +174,8 @@ public class HandleLog { */ @ProviderFor(EclipseAnnotationHandler.class) public static class HandleLog4jLog implements EclipseAnnotationHandler<lombok.extern.log4j.Log4j> { - @Override public boolean handle(AnnotationValues<lombok.extern.log4j.Log4j> annotation, Annotation source, EclipseNode annotationNode) { - return processAnnotation(LoggingFramework.LOG4J, annotation, source, annotationNode); + @Override public void handle(AnnotationValues<lombok.extern.log4j.Log4j> annotation, Annotation source, EclipseNode annotationNode) { + processAnnotation(LoggingFramework.LOG4J, annotation, source, annotationNode); } } @@ -184,8 +184,8 @@ public class HandleLog { */ @ProviderFor(EclipseAnnotationHandler.class) public static class HandleSlf4jLog implements EclipseAnnotationHandler<lombok.extern.slf4j.Slf4j> { - @Override public boolean handle(AnnotationValues<lombok.extern.slf4j.Slf4j> annotation, Annotation source, EclipseNode annotationNode) { - return processAnnotation(LoggingFramework.SLF4J, annotation, source, annotationNode); + @Override public void handle(AnnotationValues<lombok.extern.slf4j.Slf4j> annotation, Annotation source, EclipseNode annotationNode) { + processAnnotation(LoggingFramework.SLF4J, annotation, source, annotationNode); } } diff --git a/src/core/lombok/eclipse/handlers/HandlePrintAST.java b/src/core/lombok/eclipse/handlers/HandlePrintAST.java index 580a54a2..be86a566 100644 --- a/src/core/lombok/eclipse/handlers/HandlePrintAST.java +++ b/src/core/lombok/eclipse/handlers/HandlePrintAST.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 @@ -40,8 +40,8 @@ import lombok.eclipse.EclipseNode; */ @ProviderFor(EclipseAnnotationHandler.class) public class HandlePrintAST implements EclipseAnnotationHandler<PrintAST> { - public boolean handle(AnnotationValues<PrintAST> annotation, Annotation ast, EclipseNode annotationNode) { - if (!annotationNode.isCompleteParse()) return false; + public void handle(AnnotationValues<PrintAST> annotation, Annotation ast, EclipseNode annotationNode) { + if (!annotationNode.isCompleteParse()) return; PrintStream stream = System.out; String fileName = annotation.getInstance().outfile(); @@ -52,6 +52,5 @@ public class HandlePrintAST implements EclipseAnnotationHandler<PrintAST> { } annotationNode.up().traverse(new EclipseASTVisitor.Printer(annotation.getInstance().printContent(), stream)); - return true; } } diff --git a/src/core/lombok/eclipse/handlers/HandleSetter.java b/src/core/lombok/eclipse/handlers/HandleSetter.java index 945495c6..ac3ff2a2 100644 --- a/src/core/lombok/eclipse/handlers/HandleSetter.java +++ b/src/core/lombok/eclipse/handlers/HandleSetter.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 @@ -120,40 +120,37 @@ public class HandleSetter implements EclipseAnnotationHandler<Setter> { createSetterForField(level, fieldNode, fieldNode, pos, false, onMethod, onParam); } - public boolean handle(AnnotationValues<Setter> annotation, Annotation ast, EclipseNode annotationNode) { + public void handle(AnnotationValues<Setter> annotation, Annotation ast, EclipseNode annotationNode) { EclipseNode node = annotationNode.up(); AccessLevel level = annotation.getInstance().value(); - if (level == AccessLevel.NONE) return true; - - if (node == null) return false; + if (level == AccessLevel.NONE || node == null) return; Annotation[] onMethod = getAndRemoveAnnotationParameter(ast, "onMethod"); Annotation[] onParam = getAndRemoveAnnotationParameter(ast, "onParam"); - if (node.getKind() == Kind.FIELD) { - return createSetterForFields(level, annotationNode.upFromAnnotationToFields(), annotationNode, annotationNode.get(), true, onMethod, onParam); - - } - if (node.getKind() == Kind.TYPE) { + switch (node.getKind()) { + case FIELD: + createSetterForFields(level, annotationNode.upFromAnnotationToFields(), annotationNode, annotationNode.get(), true, onMethod, onParam); + break; + case TYPE: if (onMethod != null && onMethod.length != 0) annotationNode.addError("'onMethod' is not supported for @Setter on a type."); if (onParam != null && onParam.length != 0) annotationNode.addError("'onParam' is not supported for @Setter on a type."); - return generateSetterForType(node, annotationNode, level, false); + generateSetterForType(node, annotationNode, level, false); + break; } - return false; } - private boolean createSetterForFields(AccessLevel level, Collection<EclipseNode> fieldNodes, EclipseNode errorNode, ASTNode source, boolean whineIfExists, Annotation[] onMethod , Annotation[] onParam) { + private void createSetterForFields(AccessLevel level, Collection<EclipseNode> fieldNodes, EclipseNode errorNode, ASTNode source, boolean whineIfExists, Annotation[] onMethod , Annotation[] onParam) { for (EclipseNode fieldNode : fieldNodes) { createSetterForField(level, fieldNode, errorNode, source, whineIfExists, onMethod, onParam); } - return true; } - private boolean createSetterForField(AccessLevel level, + private void createSetterForField(AccessLevel level, EclipseNode fieldNode, EclipseNode errorNode, ASTNode source, boolean whineIfExists, Annotation[] onMethod , Annotation[] onParam) { if (fieldNode.getKind() != Kind.FIELD) { errorNode.addError("@Setter is only supported on a class or a field."); - return true; + return; } FieldDeclaration field = (FieldDeclaration) fieldNode.get(); @@ -166,7 +163,7 @@ public class HandleSetter implements EclipseAnnotationHandler<Setter> { for (String altName : TransformationsUtil.toAllSetterNames(new String(field.name), isBoolean)) { switch (methodExists(altName, fieldNode, false)) { case EXISTS_BY_LOMBOK: - return true; + return; case EXISTS_BY_USER: if (whineIfExists) { String altNameExpl = ""; @@ -174,7 +171,7 @@ public class HandleSetter implements EclipseAnnotationHandler<Setter> { errorNode.addWarning( String.format("Not generating %s(): A method with that name already exists%s", setterName, altNameExpl)); } - return true; + return; default: case NOT_EXISTS: //continue scanning the other alt names. @@ -188,8 +185,6 @@ public class HandleSetter implements EclipseAnnotationHandler<Setter> { } injectMethod(fieldNode.up(), method); - - return true; } private MethodDeclaration generateSetter(TypeDeclaration parent, EclipseNode fieldNode, String name, int modifier, ASTNode source, Annotation[] onParam) { diff --git a/src/core/lombok/eclipse/handlers/HandleSneakyThrows.java b/src/core/lombok/eclipse/handlers/HandleSneakyThrows.java index 38f22b2a..4b36d688 100644 --- a/src/core/lombok/eclipse/handlers/HandleSneakyThrows.java +++ b/src/core/lombok/eclipse/handlers/HandleSneakyThrows.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 @@ -69,7 +69,7 @@ public class HandleSneakyThrows implements EclipseAnnotationHandler<SneakyThrows } } - @Override public boolean handle(AnnotationValues<SneakyThrows> annotation, Annotation source, EclipseNode annotationNode) { + @Override public void handle(AnnotationValues<SneakyThrows> annotation, Annotation source, EclipseNode annotationNode) { List<String> exceptionNames = annotation.getRawExpressions("value"); List<DeclaredException> exceptions = new ArrayList<DeclaredException>(); @@ -101,10 +101,10 @@ public class HandleSneakyThrows implements EclipseAnnotationHandler<SneakyThrows // case FIELD: // return handleField(annotationNode, (FieldDeclaration)owner.get(), exceptions); case METHOD: - return handleMethod(annotationNode, (AbstractMethodDeclaration)owner.get(), exceptions); + handleMethod(annotationNode, (AbstractMethodDeclaration)owner.get(), exceptions); + break; default: annotationNode.addError("@SneakyThrows is legal only on methods and constructors."); - return true; } } @@ -140,13 +140,13 @@ public class HandleSneakyThrows implements EclipseAnnotationHandler<SneakyThrows // return true; // } - private boolean handleMethod(EclipseNode annotation, AbstractMethodDeclaration method, List<DeclaredException> exceptions) { + private void handleMethod(EclipseNode annotation, AbstractMethodDeclaration method, List<DeclaredException> exceptions) { if (method.isAbstract()) { annotation.addError("@SneakyThrows can only be used on concrete methods."); - return true; + return; } - if (method.statements == null) return false; + if (method.statements == null) return; Statement[] contents = method.statements; @@ -156,8 +156,6 @@ public class HandleSneakyThrows implements EclipseAnnotationHandler<SneakyThrows method.statements = contents; annotation.up().rebuild(); - - return true; } private Statement buildTryCatchBlock(Statement[] contents, DeclaredException exception, ASTNode source) { diff --git a/src/core/lombok/eclipse/handlers/HandleSynchronized.java b/src/core/lombok/eclipse/handlers/HandleSynchronized.java index b77099b5..ace1c6dc 100644 --- a/src/core/lombok/eclipse/handlers/HandleSynchronized.java +++ b/src/core/lombok/eclipse/handlers/HandleSynchronized.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 @@ -57,20 +57,20 @@ public class HandleSynchronized implements EclipseAnnotationHandler<Synchronized private static final char[] INSTANCE_LOCK_NAME = "$lock".toCharArray(); private static final char[] STATIC_LOCK_NAME = "$LOCK".toCharArray(); - @Override public boolean handle(AnnotationValues<Synchronized> annotation, Annotation source, EclipseNode annotationNode) { + @Override public void handle(AnnotationValues<Synchronized> annotation, Annotation source, EclipseNode annotationNode) { int p1 = source.sourceStart -1; int p2 = source.sourceStart -2; long pos = (((long)p1) << 32) | p2; EclipseNode methodNode = annotationNode.up(); if (methodNode == null || methodNode.getKind() != Kind.METHOD || !(methodNode.get() instanceof MethodDeclaration)) { annotationNode.addError("@Synchronized is legal only on methods."); - return true; + return; } MethodDeclaration method = (MethodDeclaration)methodNode.get(); if (method.isAbstract()) { annotationNode.addError("@Synchronized is legal only on concrete methods."); - return true; + return; } char[] lockName = annotation.getInstance().value().toCharArray(); @@ -83,7 +83,7 @@ public class HandleSynchronized implements EclipseAnnotationHandler<Synchronized if (fieldExists(new String(lockName), methodNode) == MemberExistsResult.NOT_EXISTS) { if (!autoMake) { annotationNode.addError("The field " + new String(lockName) + " does not exist."); - return true; + return; } FieldDeclaration fieldDecl = new FieldDeclaration(lockName, 0, -1); Eclipse.setGeneratedBy(fieldDecl, source); @@ -104,7 +104,7 @@ public class HandleSynchronized implements EclipseAnnotationHandler<Synchronized injectFieldSuppressWarnings(annotationNode.up().up(), fieldDecl); } - if (method.statements == null) return false; + if (method.statements == null) return; Block block = new Block(0); Eclipse.setGeneratedBy(block, source); @@ -126,7 +126,5 @@ public class HandleSynchronized implements EclipseAnnotationHandler<Synchronized Eclipse.setGeneratedBy(method.statements[0], source); methodNode.rebuild(); - - return true; } } diff --git a/src/core/lombok/eclipse/handlers/HandleToString.java b/src/core/lombok/eclipse/handlers/HandleToString.java index 8d722247..553f097b 100644 --- a/src/core/lombok/eclipse/handlers/HandleToString.java +++ b/src/core/lombok/eclipse/handlers/HandleToString.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 @@ -98,7 +98,7 @@ public class HandleToString implements EclipseAnnotationHandler<ToString> { generateToString(typeNode, errorNode, null, null, includeFieldNames, null, false, FieldAccess.GETTER); } - public boolean handle(AnnotationValues<ToString> annotation, Annotation ast, EclipseNode annotationNode) { + public void handle(AnnotationValues<ToString> annotation, Annotation ast, EclipseNode annotationNode) { ToString ann = annotation.getInstance(); List<String> excludes = Arrays.asList(ann.exclude()); List<String> includes = Arrays.asList(ann.of()); @@ -118,10 +118,10 @@ public class HandleToString implements EclipseAnnotationHandler<ToString> { FieldAccess fieldAccess = ann.doNotUseGetters() ? FieldAccess.PREFER_FIELD : FieldAccess.GETTER; - return generateToString(typeNode, annotationNode, excludes, includes, ann.includeFieldNames(), callSuper, true, fieldAccess); + generateToString(typeNode, annotationNode, excludes, includes, ann.includeFieldNames(), callSuper, true, fieldAccess); } - public boolean generateToString(EclipseNode typeNode, EclipseNode errorNode, List<String> excludes, List<String> includes, + public void generateToString(EclipseNode typeNode, EclipseNode errorNode, List<String> excludes, List<String> includes, boolean includeFieldNames, Boolean callSuper, boolean whineIfExists, FieldAccess fieldAccess) { TypeDeclaration typeDecl = null; @@ -132,7 +132,6 @@ public class HandleToString implements EclipseAnnotationHandler<ToString> { if (typeDecl == null || notAClass) { errorNode.addError("@ToString is only supported on a class or enum."); - return false; } if (callSuper == null) { @@ -165,15 +164,14 @@ public class HandleToString implements EclipseAnnotationHandler<ToString> { case NOT_EXISTS: MethodDeclaration toString = createToString(typeNode, nodesForToString, includeFieldNames, callSuper, errorNode.get(), fieldAccess); injectMethod(typeNode, toString); - return true; + break; case EXISTS_BY_LOMBOK: - return true; + break; default: case EXISTS_BY_USER: if (whineIfExists) { errorNode.addWarning("Not generating toString(): A method with that name already exists"); } - return true; } } 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 JavacAnnotationHandler<EqualsAnd FieldAccess fieldAccess = ann.doNotUseGetters() ? FieldAccess.PREFER_FIELD : FieldAccess.GETTER; - return generateMethods(typeNode, annotationNode, excludes, includes, callSuper, true, fieldAccess); + generateMethods(typeNode, annotationNode, excludes, includes, callSuper, true, fieldAccess); } - public void generateEqualsAndHashCodeForType(JavacNode typeNode, JavacNode errorNode) { + public void generateEqualsAndHashCodeForType(JavacNode typeNode, JavacNode source) { for (JavacNode child : typeNode.down()) { if (child.getKind() == Kind.ANNOTATION) { if (Javac.annotationTypeMatches(EqualsAndHashCode.class, child)) { @@ -106,10 +106,10 @@ public class HandleEqualsAndHashCode implements JavacAnnotationHandler<EqualsAnd } } - generateMethods(typeNode, errorNode, null, null, null, false, FieldAccess.GETTER); + generateMethods(typeNode, source, null, null, null, false, FieldAccess.GETTER); } - private boolean generateMethods(JavacNode typeNode, JavacNode errorNode, List<String> excludes, List<String> includes, + private void generateMethods(JavacNode typeNode, JavacNode source, List<String> excludes, List<String> includes, Boolean callSuper, boolean whineIfExists, FieldAccess fieldAccess) { boolean notAClass = true; if (typeNode.get() instanceof JCClassDecl) { @@ -118,8 +118,8 @@ public class HandleEqualsAndHashCode implements JavacAnnotationHandler<EqualsAnd } if (notAClass) { - errorNode.addError("@EqualsAndHashCode is only supported on a class."); - return false; + source.addError("@EqualsAndHashCode is only supported on a class."); + return; } boolean isDirectDescendantOfObject = true; @@ -139,12 +139,12 @@ public class HandleEqualsAndHashCode implements JavacAnnotationHandler<EqualsAnd } if (isDirectDescendantOfObject && callSuper) { - errorNode.addError("Generating equals/hashCode with a supercall to java.lang.Object is pointless."); - return true; + source.addError("Generating equals/hashCode with a supercall to java.lang.Object is pointless."); + return; } if (!isDirectDescendantOfObject && !callSuper && implicitCallSuper) { - errorNode.addWarning("Generating equals/hashCode implementation but without a call to superclass, even though this class does not extend java.lang.Object. If this is intentional, add '@EqualsAndHashCode(callSuper=false)' to your type."); + source.addWarning("Generating equals/hashCode implementation but without a call to superclass, even though this class does not extend java.lang.Object. If this is intentional, add '@EqualsAndHashCode(callSuper=false)' to your type."); } ListBuffer<JavacNode> nodesForEquality = ListBuffer.lb(); @@ -176,7 +176,7 @@ public class HandleEqualsAndHashCode implements JavacAnnotationHandler<EqualsAnd boolean isFinal = (((JCClassDecl)typeNode.get()).mods.flags & Flags.FINAL) != 0; needsCanEqual = !isFinal || !isDirectDescendantOfObject; - JCMethodDecl method = createEquals(typeNode, nodesForEquality.toList(), callSuper, fieldAccess, needsCanEqual); + JCMethodDecl method = createEquals(typeNode, nodesForEquality.toList(), callSuper, fieldAccess, needsCanEqual, source.get()); injectMethod(typeNode, method); break; case EXISTS_BY_LOMBOK: @@ -184,7 +184,7 @@ public class HandleEqualsAndHashCode implements JavacAnnotationHandler<EqualsAnd default: case EXISTS_BY_USER: if (whineIfExists) { - errorNode.addWarning("Not generating equals(Object other): A method with that name already exists"); + source.addWarning("Not generating equals(Object other): A method with that name already exists"); } break; } @@ -192,7 +192,7 @@ public class HandleEqualsAndHashCode implements JavacAnnotationHandler<EqualsAnd if (needsCanEqual) { switch (methodExists("canEqual", typeNode)) { case NOT_EXISTS: - JCMethodDecl method = createCanEqual(typeNode); + JCMethodDecl method = createCanEqual(typeNode, source.get()); injectMethod(typeNode, method); break; case EXISTS_BY_LOMBOK: @@ -203,7 +203,7 @@ public class HandleEqualsAndHashCode implements JavacAnnotationHandler<EqualsAnd } switch (methodExists("hashCode", typeNode)) { case NOT_EXISTS: - JCMethodDecl method = createHashCode(typeNode, nodesForEquality.toList(), callSuper, fieldAccess); + JCMethodDecl method = createHashCode(typeNode, nodesForEquality.toList(), callSuper, fieldAccess, source.get()); injectMethod(typeNode, method); break; case EXISTS_BY_LOMBOK: @@ -211,14 +211,13 @@ public class HandleEqualsAndHashCode implements JavacAnnotationHandler<EqualsAnd default: case EXISTS_BY_USER: if (whineIfExists) { - errorNode.addWarning("Not generating hashCode(): A method with that name already exists"); + source.addWarning("Not generating hashCode(): A method with that name already exists"); } break; } - return true; } - private JCMethodDecl createHashCode(JavacNode typeNode, List<JavacNode> fields, boolean callSuper, FieldAccess fieldAccess) { + private JCMethodDecl createHashCode(JavacNode typeNode, List<JavacNode> fields, boolean callSuper, FieldAccess fieldAccess, JCTree source) { TreeMaker maker = typeNode.getTreeMaker(); JCAnnotation overrideAnnotation = maker.Annotation(chainDots(maker, typeNode, "java", "lang", "Override"), List.<JCExpression>nil()); @@ -320,8 +319,8 @@ public class HandleEqualsAndHashCode implements JavacAnnotationHandler<EqualsAnd } JCBlock body = maker.Block(0, statements.toList()); - return maker.MethodDef(mods, typeNode.toName("hashCode"), returnType, - List.<JCTypeParameter>nil(), List.<JCVariableDecl>nil(), List.<JCExpression>nil(), body, null); + return Javac.recursiveSetGeneratedBy(maker.MethodDef(mods, typeNode.toName("hashCode"), returnType, + List.<JCTypeParameter>nil(), List.<JCVariableDecl>nil(), List.<JCExpression>nil(), body, null), source); } /** The 2 references must be clones of each other. */ @@ -332,7 +331,7 @@ public class HandleEqualsAndHashCode implements JavacAnnotationHandler<EqualsAnd return maker.TypeCast(maker.TypeIdent(Javac.getCTCint(TypeTags.class, "INT")), xorBits); } - private JCMethodDecl createEquals(JavacNode typeNode, List<JavacNode> fields, boolean callSuper, FieldAccess fieldAccess, boolean needsCanEqual) { + private JCMethodDecl createEquals(JavacNode typeNode, List<JavacNode> fields, boolean callSuper, FieldAccess fieldAccess, boolean needsCanEqual, JCTree source) { TreeMaker maker = typeNode.getTreeMaker(); JCClassDecl type = (JCClassDecl) typeNode.get(); @@ -451,10 +450,10 @@ public class HandleEqualsAndHashCode implements JavacAnnotationHandler<EqualsAnd } JCBlock body = maker.Block(0, statements.toList()); - return maker.MethodDef(mods, typeNode.toName("equals"), returnType, List.<JCTypeParameter>nil(), params, List.<JCExpression>nil(), body, null); + return Javac.recursiveSetGeneratedBy(maker.MethodDef(mods, typeNode.toName("equals"), returnType, List.<JCTypeParameter>nil(), params, List.<JCExpression>nil(), body, null), source); } - private JCMethodDecl createCanEqual(JavacNode typeNode) { + private JCMethodDecl createCanEqual(JavacNode typeNode, JCTree source) { /* public boolean canEqual(final java.lang.Object other) { * return other instanceof MyType; * } @@ -472,7 +471,7 @@ public class HandleEqualsAndHashCode implements JavacAnnotationHandler<EqualsAnd JCBlock body = maker.Block(0, List.<JCStatement>of( maker.Return(maker.TypeTest(maker.Ident(otherName), maker.Ident(type.name))))); - return maker.MethodDef(mods, canEqualName, returnType, List.<JCTypeParameter>nil(), params, List.<JCExpression>nil(), body, null); + return Javac.recursiveSetGeneratedBy(maker.MethodDef(mods, canEqualName, returnType, List.<JCTypeParameter>nil(), params, List.<JCExpression>nil(), body, null), source); } private JCStatement generateCompareFloatOrDouble(JCExpression thisDotField, JCExpression otherDotField, diff --git a/src/core/lombok/javac/handlers/HandleGetter.java b/src/core/lombok/javac/handlers/HandleGetter.java index 8a1f7eed..83b6a898 100644 --- a/src/core/lombok/javac/handlers/HandleGetter.java +++ b/src/core/lombok/javac/handlers/HandleGetter.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 @@ -70,13 +70,13 @@ import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; */ @ProviderFor(JavacAnnotationHandler.class) public class HandleGetter implements JavacAnnotationHandler<Getter> { - public boolean generateGetterForType(JavacNode typeNode, JavacNode errorNode, AccessLevel level, boolean checkForTypeLevelGetter) { + public void generateGetterForType(JavacNode typeNode, JavacNode errorNode, AccessLevel level, boolean checkForTypeLevelGetter) { if (checkForTypeLevelGetter) { if (typeNode != null) for (JavacNode child : typeNode.down()) { if (child.getKind() == Kind.ANNOTATION) { if (Javac.annotationTypeMatches(Getter.class, child)) { //The annotation will make it happen, so we can skip it. - return true; + return; } } } @@ -89,14 +89,12 @@ public class HandleGetter implements JavacAnnotationHandler<Getter> { if (typeDecl == null || notAClass) { errorNode.addError("@Getter is only supported on a class, an enum, or a field."); - return false; + return; } for (JavacNode field : typeNode.down()) { if (fieldQualifiesForGetterGeneration(field)) generateGetterForField(field, errorNode.get(), level, List.<JCExpression>nil(), false); } - - return true; } public boolean fieldQualifiesForGetterGeneration(JavacNode field) { @@ -123,7 +121,6 @@ public class HandleGetter implements JavacAnnotationHandler<Getter> { * * @param fieldNode The node representing the field you want a getter for. * @param pos The node responsible for generating the getter (the {@code @Data} or {@code @Getter} annotation). - * @param lazy */ public void generateGetterForField(JavacNode fieldNode, DiagnosticPosition pos, AccessLevel level, List<JCExpression> onMethod, boolean lazy) { for (JavacNode child : fieldNode.down()) { @@ -138,9 +135,9 @@ public class HandleGetter implements JavacAnnotationHandler<Getter> { createGetterForField(level, fieldNode, fieldNode, false, onMethod, lazy); } - @Override public boolean handle(AnnotationValues<Getter> annotation, JCAnnotation ast, JavacNode annotationNode) { + @Override public void handle(AnnotationValues<Getter> annotation, JCAnnotation ast, JavacNode annotationNode) { Collection<JavacNode> fields = annotationNode.upFromAnnotationToFields(); - markAnnotationAsProcessed(annotationNode, Getter.class); + deleteAnnotationIfNeccessary(annotationNode, Getter.class); deleteImportFromCompilationUnit(annotationNode, "lombok.AccessLevel"); JavacNode node = annotationNode.up(); Getter annotationInstance = annotation.getInstance(); @@ -150,48 +147,47 @@ public class HandleGetter implements JavacAnnotationHandler<Getter> { if (lazy) { annotationNode.addWarning("'lazy' does not work with AccessLevel.NONE."); } - return true; + return; } - if (node == null) return false; + if (node == null) return; List<JCExpression> onMethod = getAndRemoveAnnotationParameter(ast, "onMethod"); - if (node.getKind() == Kind.FIELD) { - return createGetterForFields(level, fields, annotationNode, true, onMethod, lazy); - } - if (node.getKind() == Kind.TYPE) { + switch (node.getKind()) { + case FIELD: + createGetterForFields(level, fields, annotationNode, true, onMethod, lazy); + break; + case TYPE: if (!onMethod.isEmpty()) annotationNode.addError("'onMethod' is not supported for @Getter on a type."); if (lazy) annotationNode.addError("'lazy' is not supported for @Getter on a type."); - return generateGetterForType(node, annotationNode, level, false); + generateGetterForType(node, annotationNode, level, false); + break; } - return false; } - private boolean createGetterForFields(AccessLevel level, Collection<JavacNode> fieldNodes, JavacNode errorNode, boolean whineIfExists, List<JCExpression> onMethod, boolean lazy) { + private void createGetterForFields(AccessLevel level, Collection<JavacNode> fieldNodes, JavacNode errorNode, boolean whineIfExists, List<JCExpression> onMethod, boolean lazy) { for (JavacNode fieldNode : fieldNodes) { createGetterForField(level, fieldNode, errorNode, whineIfExists, onMethod, lazy); } - - return true; } - private boolean createGetterForField(AccessLevel level, - JavacNode fieldNode, JavacNode errorNode, boolean whineIfExists, List<JCExpression> onMethod, boolean lazy) { + private void createGetterForField(AccessLevel level, + JavacNode fieldNode, JavacNode source, boolean whineIfExists, List<JCExpression> onMethod, boolean lazy) { if (fieldNode.getKind() != Kind.FIELD) { - errorNode.addError("@Getter is only supported on a class or a field."); - return true; + source.addError("@Getter is only supported on a class or a field."); + return; } JCVariableDecl fieldDecl = (JCVariableDecl)fieldNode.get(); if (lazy) { if ((fieldDecl.mods.flags & Flags.PRIVATE) == 0 || (fieldDecl.mods.flags & Flags.FINAL) == 0) { - errorNode.addError("'lazy' requires the field to be private and final."); - return true; + source.addError("'lazy' requires the field to be private and final."); + return; } if (fieldDecl.init == null) { - errorNode.addError("'lazy' requires field initialization."); - return true; + source.addError("'lazy' requires field initialization."); + return; } } @@ -200,15 +196,15 @@ public class HandleGetter implements JavacAnnotationHandler<Getter> { for (String altName : toAllGetterNames(fieldDecl)) { switch (methodExists(altName, fieldNode, false)) { case EXISTS_BY_LOMBOK: - return true; + return; case EXISTS_BY_USER: if (whineIfExists) { String altNameExpl = ""; if (!altName.equals(methodName)) altNameExpl = String.format(" (%s)", altName); - errorNode.addWarning( + source.addWarning( String.format("Not generating %s(): A method with that name already exists%s", methodName, altNameExpl)); } - return true; + return; default: case NOT_EXISTS: //continue scanning the other alt names. @@ -217,20 +213,20 @@ public class HandleGetter implements JavacAnnotationHandler<Getter> { long access = toJavacModifier(level) | (fieldDecl.mods.flags & Flags.STATIC); - injectMethod(fieldNode.up(), createGetter(access, fieldNode, fieldNode.getTreeMaker(), onMethod, lazy)); - - return true; + injectMethod(fieldNode.up(), createGetter(access, fieldNode, fieldNode.getTreeMaker(), onMethod, lazy, source.get())); } - private JCMethodDecl createGetter(long access, JavacNode field, TreeMaker treeMaker, List<JCExpression> onMethod, boolean lazy) { + private JCMethodDecl createGetter(long access, JavacNode field, TreeMaker treeMaker, List<JCExpression> onMethod, boolean lazy, JCTree source) { JCVariableDecl fieldNode = (JCVariableDecl) field.get(); // Remember the type; lazy will change it; JCExpression methodType = copyType(treeMaker, fieldNode); List<JCStatement> statements; + JCTree toClearOfMarkers = null; if (lazy) { - statements = createLazyGetterBody(treeMaker, field); + toClearOfMarkers = fieldNode.init; + statements = createLazyGetterBody(treeMaker, field, source); } else { statements = createSimpleGetterBody(treeMaker, field); } @@ -248,8 +244,12 @@ public class HandleGetter implements JavacAnnotationHandler<Getter> { List<JCAnnotation> annsOnMethod = copyAnnotations(onMethod).appendList(nonNulls).appendList(nullables); - return treeMaker.MethodDef(treeMaker.Modifiers(access, annsOnMethod), methodName, methodType, - methodGenericParams, parameters, throwsClauses, methodBody, annotationMethodDefaultValue); + JCMethodDecl decl = Javac.recursiveSetGeneratedBy(treeMaker.MethodDef(treeMaker.Modifiers(access, annsOnMethod), methodName, methodType, + methodGenericParams, parameters, throwsClauses, methodBody, annotationMethodDefaultValue), source); + + if (toClearOfMarkers != null) Javac.recursiveSetGeneratedBy(toClearOfMarkers, null); + + return decl; } private List<JCStatement> createSimpleGetterBody(TreeMaker treeMaker, JavacNode field) { @@ -273,7 +273,7 @@ public class HandleGetter implements JavacAnnotationHandler<Getter> { TYPE_MAP = Collections.unmodifiableMap(m); } - private List<JCStatement> createLazyGetterBody(TreeMaker maker, JavacNode fieldNode) { + private List<JCStatement> createLazyGetterBody(TreeMaker maker, JavacNode fieldNode, JCTree source) { /* java.util.concurrent.atomic.AtomicReference<ValueType> value = this.fieldName.get(); if (value == null) { @@ -318,7 +318,7 @@ public class HandleGetter implements JavacAnnotationHandler<Getter> { /* if (value == null) { */ { ListBuffer<JCStatement> innerIfStatements = ListBuffer.lb(); /* value = new java.util.concurrent.atomic.AtomicReference<ValueType>(new ValueType());*/ { - JCTypeApply valueVarType = maker.TypeApply(chainDotsString(maker, fieldNode, AR), List.of(copyType(maker, field))); + JCTypeApply valueVarType = maker.TypeApply(chainDotsString(maker, fieldNode, AR), List.of(copyType(maker, field))); JCNewClass newInstance = maker.NewClass(null, NIL_EXPRESSION, valueVarType, List.<JCExpression>of(field.init), null); JCStatement statement = maker.Exec(maker.Assign(maker.Ident(valueName), newInstance)); @@ -347,8 +347,10 @@ public class HandleGetter implements JavacAnnotationHandler<Getter> { // update the field type and init last /* private final java.util.concurrent.atomic.AtomicReference<java.util.concurrent.atomic.AtomicReference<ValueType> fieldName = new java.util.concurrent.atomic.AtomicReference<java.util.concurrent.atomic.AtomicReference<ValueType>>(); */ { - field.vartype = maker.TypeApply(chainDotsString(maker, fieldNode, AR), List.<JCExpression>of(maker.TypeApply(chainDotsString(maker, fieldNode, AR), List.of(copyType(maker, field))))); - field.init = maker.NewClass(null, NIL_EXPRESSION, copyType(maker, field), NIL_EXPRESSION, null); + field.vartype = Javac.recursiveSetGeneratedBy( + maker.TypeApply(chainDotsString(maker, fieldNode, AR), List.<JCExpression>of(maker.TypeApply(chainDotsString(maker, fieldNode, AR), List.of(copyType(maker, field))))), + source); + field.init = Javac.recursiveSetGeneratedBy(maker.NewClass(null, NIL_EXPRESSION, copyType(maker, field), NIL_EXPRESSION, null), source); } return statements.toList(); diff --git a/src/core/lombok/javac/handlers/HandleLog.java b/src/core/lombok/javac/handlers/HandleLog.java index 53d327af..f4a4dead 100644 --- a/src/core/lombok/javac/handlers/HandleLog.java +++ b/src/core/lombok/javac/handlers/HandleLog.java @@ -1,5 +1,5 @@ /* - * Copyright © 2010 Reinier Zwitserloot, Roel Spilker and Robbert Jan Grootjans. + * Copyright © 2010-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 @@ -26,6 +26,7 @@ import static lombok.javac.handlers.JavacHandlerUtil.*; import java.lang.annotation.Annotation; import lombok.core.AnnotationValues; +import lombok.javac.Javac; import lombok.javac.JavacAnnotationHandler; import lombok.javac.JavacNode; import lombok.javac.handlers.JavacHandlerUtil.MemberExistsResult; @@ -33,6 +34,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.JCClassDecl; @@ -49,28 +51,28 @@ public class HandleLog { throw new UnsupportedOperationException(); } - public static boolean processAnnotation(LoggingFramework framework, AnnotationValues<?> annotation, JavacNode annotationNode) { - markAnnotationAsProcessed(annotationNode, framework.getAnnotationClass()); + public static void processAnnotation(LoggingFramework framework, AnnotationValues<?> annotation, JavacNode annotationNode) { + deleteAnnotationIfNeccessary(annotationNode, framework.getAnnotationClass()); JavacNode typeNode = annotationNode.up(); switch (typeNode.getKind()) { case TYPE: if ((((JCClassDecl)typeNode.get()).mods.flags & Flags.INTERFACE)!= 0) { annotationNode.addError("@Log is legal only on classes and enums."); - return true; + return; } if (fieldExists("log", typeNode)!= MemberExistsResult.NOT_EXISTS) { annotationNode.addWarning("Field 'log' already exists."); - return true; + return; } - + JCFieldAccess loggingType = selfType(typeNode); - createField(framework, typeNode, loggingType); - return true; + createField(framework, typeNode, loggingType, annotationNode.get()); + break; default: annotationNode.addError("@Log is legal only on types."); - return true; + break; } } @@ -80,7 +82,7 @@ public class HandleLog { return maker.Select(maker.Ident(name), typeNode.toName("class")); } - private static boolean createField(LoggingFramework framework, JavacNode typeNode, JCFieldAccess loggingType) { + private static boolean createField(LoggingFramework framework, JavacNode typeNode, JCFieldAccess loggingType, JCTree source) { TreeMaker maker = typeNode.getTreeMaker(); // private static final <loggerType> log = <factoryMethod>(<parameter>); @@ -90,9 +92,9 @@ public class HandleLog { JCExpression loggerName = framework.createFactoryParameter(typeNode, loggingType); JCMethodInvocation factoryMethodCall = maker.Apply(List.<JCExpression>nil(), factoryMethod, List.<JCExpression>of(loggerName)); - JCVariableDecl fieldDecl = maker.VarDef( + JCVariableDecl fieldDecl = Javac.recursiveSetGeneratedBy(maker.VarDef( maker.Modifiers(Flags.PRIVATE | Flags.FINAL | Flags.STATIC), - typeNode.toName("log"), loggerType, factoryMethodCall); + typeNode.toName("log"), loggerType, factoryMethodCall), source); injectField(typeNode, fieldDecl); return true; @@ -103,8 +105,8 @@ public class HandleLog { */ @ProviderFor(JavacAnnotationHandler.class) public static class HandleCommonsLog implements JavacAnnotationHandler<lombok.extern.apachecommons.CommonsLog> { - @Override public boolean handle(AnnotationValues<lombok.extern.apachecommons.CommonsLog> annotation, JCAnnotation ast, JavacNode annotationNode) { - return processAnnotation(LoggingFramework.COMMONS, annotation, annotationNode); + @Override public void handle(AnnotationValues<lombok.extern.apachecommons.CommonsLog> annotation, JCAnnotation ast, JavacNode annotationNode) { + processAnnotation(LoggingFramework.COMMONS, annotation, annotationNode); } @Override public boolean isResolutionBased() { @@ -117,8 +119,8 @@ public class HandleLog { */ @ProviderFor(JavacAnnotationHandler.class) public static class HandleJulLog implements JavacAnnotationHandler<lombok.extern.java.Log> { - @Override public boolean handle(AnnotationValues<lombok.extern.java.Log> annotation, JCAnnotation ast, JavacNode annotationNode) { - return processAnnotation(LoggingFramework.JUL, annotation, annotationNode); + @Override public void handle(AnnotationValues<lombok.extern.java.Log> annotation, JCAnnotation ast, JavacNode annotationNode) { + processAnnotation(LoggingFramework.JUL, annotation, annotationNode); } @Override public boolean isResolutionBased() { @@ -131,8 +133,8 @@ public class HandleLog { */ @ProviderFor(JavacAnnotationHandler.class) public static class HandleLog4jLog implements JavacAnnotationHandler<lombok.extern.log4j.Log4j> { - @Override public boolean handle(AnnotationValues<lombok.extern.log4j.Log4j> annotation, JCAnnotation ast, JavacNode annotationNode) { - return processAnnotation(LoggingFramework.LOG4J, annotation, annotationNode); + @Override public void handle(AnnotationValues<lombok.extern.log4j.Log4j> annotation, JCAnnotation ast, JavacNode annotationNode) { + processAnnotation(LoggingFramework.LOG4J, annotation, annotationNode); } @Override public boolean isResolutionBased() { @@ -145,8 +147,8 @@ public class HandleLog { */ @ProviderFor(JavacAnnotationHandler.class) public static class HandleSlf4jLog implements JavacAnnotationHandler<lombok.extern.slf4j.Slf4j> { - @Override public boolean handle(AnnotationValues<lombok.extern.slf4j.Slf4j> annotation, JCAnnotation ast, JavacNode annotationNode) { - return processAnnotation(LoggingFramework.SLF4J, annotation, annotationNode); + @Override public void handle(AnnotationValues<lombok.extern.slf4j.Slf4j> annotation, JCAnnotation ast, JavacNode annotationNode) { + processAnnotation(LoggingFramework.SLF4J, annotation, annotationNode); } @Override public boolean isResolutionBased() { diff --git a/src/core/lombok/javac/handlers/HandlePrintAST.java b/src/core/lombok/javac/handlers/HandlePrintAST.java index 61b877d6..8e7612c4 100644 --- a/src/core/lombok/javac/handlers/HandlePrintAST.java +++ b/src/core/lombok/javac/handlers/HandlePrintAST.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 @@ -41,7 +41,7 @@ import lombok.javac.JavacNode; */ @ProviderFor(JavacAnnotationHandler.class) public class HandlePrintAST implements JavacAnnotationHandler<PrintAST> { - @Override public boolean handle(AnnotationValues<PrintAST> annotation, JCAnnotation ast, JavacNode annotationNode) { + @Override public void handle(AnnotationValues<PrintAST> annotation, JCAnnotation ast, JavacNode annotationNode) { PrintStream stream = System.out; String fileName = annotation.getInstance().outfile(); if (fileName.length() > 0) try { @@ -51,8 +51,6 @@ public class HandlePrintAST implements JavacAnnotationHandler<PrintAST> { } annotationNode.up().traverse(new JavacASTVisitor.Printer(annotation.getInstance().printContent(), stream)); - - return true; } @Override public boolean isResolutionBased() { diff --git a/src/core/lombok/javac/handlers/HandleSetter.java b/src/core/lombok/javac/handlers/HandleSetter.java index ec5195ac..957b02ef 100644 --- a/src/core/lombok/javac/handlers/HandleSetter.java +++ b/src/core/lombok/javac/handlers/HandleSetter.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 @@ -44,6 +44,7 @@ import org.mangosdk.spi.ProviderFor; import com.sun.tools.javac.code.Flags; import com.sun.tools.javac.code.Type; import com.sun.tools.javac.code.TypeTags; +import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.JCTree.JCAnnotation; import com.sun.tools.javac.tree.JCTree.JCAssign; import com.sun.tools.javac.tree.JCTree.JCBlock; @@ -63,13 +64,13 @@ import com.sun.tools.javac.util.Name; */ @ProviderFor(JavacAnnotationHandler.class) public class HandleSetter implements JavacAnnotationHandler<Setter> { - public boolean generateSetterForType(JavacNode typeNode, JavacNode errorNode, AccessLevel level, boolean checkForTypeLevelSetter) { + public void generateSetterForType(JavacNode typeNode, JavacNode errorNode, AccessLevel level, boolean checkForTypeLevelSetter) { if (checkForTypeLevelSetter) { if (typeNode != null) for (JavacNode child : typeNode.down()) { if (child.getKind() == Kind.ANNOTATION) { if (Javac.annotationTypeMatches(Setter.class, child)) { //The annotation will make it happen, so we can skip it. - return true; + return; } } } @@ -82,7 +83,7 @@ public class HandleSetter implements JavacAnnotationHandler<Setter> { if (typeDecl == null || notAClass) { errorNode.addError("@Setter is only supported on a class or a field."); - return false; + return; } for (JavacNode field : typeNode.down()) { @@ -97,7 +98,6 @@ public class HandleSetter implements JavacAnnotationHandler<Setter> { generateSetterForField(field, errorNode.get(), level, List.<JCExpression>nil(), List.<JCExpression>nil()); } - return true; } /** @@ -128,47 +128,45 @@ public class HandleSetter implements JavacAnnotationHandler<Setter> { createSetterForField(level, fieldNode, fieldNode, false, onMethod, onParam); } - @Override public boolean handle(AnnotationValues<Setter> annotation, JCAnnotation ast, JavacNode annotationNode) { + @Override public void handle(AnnotationValues<Setter> annotation, JCAnnotation ast, JavacNode annotationNode) { Collection<JavacNode> fields = annotationNode.upFromAnnotationToFields(); - markAnnotationAsProcessed(annotationNode, Setter.class); + deleteAnnotationIfNeccessary(annotationNode, Setter.class); deleteImportFromCompilationUnit(annotationNode, "lombok.AccessLevel"); JavacNode node = annotationNode.up(); AccessLevel level = annotation.getInstance().value(); - if (level == AccessLevel.NONE) return true; - if (node == null) return false; + if (level == AccessLevel.NONE || node == null) return; List<JCExpression> onParamList = getAndRemoveAnnotationParameter(ast, "onParam"); List<JCExpression> onMethodList = getAndRemoveAnnotationParameter(ast, "onMethod"); - if (node.getKind() == Kind.FIELD) { - return createSetterForFields(level, fields, annotationNode, true, onMethodList, onParamList); - } - if (node.getKind() == Kind.TYPE) { + switch (node.getKind()) { + case FIELD: + createSetterForFields(level, fields, annotationNode, true, onMethodList, onParamList); + break; + case TYPE: if (!onMethodList.isEmpty()) annotationNode.addError("'onMethod' is not supported for @Setter on a type."); if (!onParamList.isEmpty()) annotationNode.addError("'onParam' is not supported for @Setter on a type."); - return generateSetterForType(node, annotationNode, level, false); + generateSetterForType(node, annotationNode, level, false); + break; } - return false; } - private boolean createSetterForFields(AccessLevel level, Collection<JavacNode> fieldNodes, JavacNode errorNode, boolean whineIfExists, + private void createSetterForFields(AccessLevel level, Collection<JavacNode> fieldNodes, JavacNode errorNode, boolean whineIfExists, List<JCExpression> onMethod, List<JCExpression> onParam) { for (JavacNode fieldNode : fieldNodes) { createSetterForField(level, fieldNode, errorNode, whineIfExists, onMethod, onParam); } - - return true; } - private boolean createSetterForField(AccessLevel level, - JavacNode fieldNode, JavacNode errorNode, boolean whineIfExists, List<JCExpression> onMethod, List<JCExpression> onParam) { + private void createSetterForField(AccessLevel level, + JavacNode fieldNode, JavacNode source, boolean whineIfExists, List<JCExpression> onMethod, List<JCExpression> onParam) { if (fieldNode.getKind() != Kind.FIELD) { fieldNode.addError("@Setter is only supported on a class or a field."); - return true; + return; } JCVariableDecl fieldDecl = (JCVariableDecl)fieldNode.get(); @@ -177,15 +175,15 @@ public class HandleSetter implements JavacAnnotationHandler<Setter> { for (String altName : toAllSetterNames(fieldDecl)) { switch (methodExists(altName, fieldNode, false)) { case EXISTS_BY_LOMBOK: - return true; + return; case EXISTS_BY_USER: if (whineIfExists) { String altNameExpl = ""; if (!altName.equals(methodName)) altNameExpl = String.format(" (%s)", altName); - errorNode.addWarning( + source.addWarning( String.format("Not generating %s(): A method with that name already exists%s", methodName, altNameExpl)); } - return true; + return; default: case NOT_EXISTS: //continue scanning the other alt names. @@ -194,12 +192,10 @@ public class HandleSetter implements JavacAnnotationHandler<Setter> { long access = toJavacModifier(level) | (fieldDecl.mods.flags & Flags.STATIC); - injectMethod(fieldNode.up(), createSetter(access, fieldNode, fieldNode.getTreeMaker(), onMethod, onParam)); - - return true; + injectMethod(fieldNode.up(), createSetter(access, fieldNode, fieldNode.getTreeMaker(), onMethod, onParam, source.get())); } - private JCMethodDecl createSetter(long access, JavacNode field, TreeMaker treeMaker, List<JCExpression> onMethod, List<JCExpression> onParam) { + private JCMethodDecl createSetter(long access, JavacNode field, TreeMaker treeMaker, List<JCExpression> onMethod, List<JCExpression> onParam, JCTree source) { JCVariableDecl fieldDecl = (JCVariableDecl) field.get(); JCExpression fieldRef = createFieldAccessor(treeMaker, field, FieldAccess.ALWAYS_FIELD); @@ -230,8 +226,8 @@ public class HandleSetter implements JavacAnnotationHandler<Setter> { List<JCExpression> throwsClauses = List.nil(); JCExpression annotationMethodDefaultValue = null; - return treeMaker.MethodDef(treeMaker.Modifiers(access, copyAnnotations(onMethod)), methodName, methodType, - methodGenericParams, parameters, throwsClauses, methodBody, annotationMethodDefaultValue); + return Javac.recursiveSetGeneratedBy(treeMaker.MethodDef(treeMaker.Modifiers(access, copyAnnotations(onMethod)), methodName, methodType, + methodGenericParams, parameters, throwsClauses, methodBody, annotationMethodDefaultValue), source); } private static class JCNoType extends Type implements NoType { diff --git a/src/core/lombok/javac/handlers/HandleSneakyThrows.java b/src/core/lombok/javac/handlers/HandleSneakyThrows.java index 0f37a80e..3f1e1f0e 100644 --- a/src/core/lombok/javac/handlers/HandleSneakyThrows.java +++ b/src/core/lombok/javac/handlers/HandleSneakyThrows.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 @@ -22,7 +22,7 @@ package lombok.javac.handlers; import static lombok.javac.handlers.JavacHandlerUtil.chainDots; -import static lombok.javac.handlers.JavacHandlerUtil.markAnnotationAsProcessed; +import static lombok.javac.handlers.JavacHandlerUtil.deleteAnnotationIfNeccessary; import java.util.ArrayList; import java.util.Collection; @@ -30,12 +30,14 @@ import java.util.Collections; import lombok.SneakyThrows; import lombok.core.AnnotationValues; +import lombok.javac.Javac; import lombok.javac.JavacAnnotationHandler; import lombok.javac.JavacNode; 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.JCBlock; @@ -50,8 +52,8 @@ import com.sun.tools.javac.util.List; */ @ProviderFor(JavacAnnotationHandler.class) public class HandleSneakyThrows implements JavacAnnotationHandler<SneakyThrows> { - @Override public boolean handle(AnnotationValues<SneakyThrows> annotation, JCAnnotation ast, JavacNode annotationNode) { - markAnnotationAsProcessed(annotationNode, SneakyThrows.class); + @Override public void handle(AnnotationValues<SneakyThrows> annotation, JCAnnotation ast, JavacNode annotationNode) { + deleteAnnotationIfNeccessary(annotationNode, SneakyThrows.class); Collection<String> exceptionNames = annotation.getRawExpressions("value"); if (exceptionNames.isEmpty()) { exceptionNames = Collections.singleton("java.lang.Throwable"); @@ -66,39 +68,38 @@ public class HandleSneakyThrows implements JavacAnnotationHandler<SneakyThrows> JavacNode owner = annotationNode.up(); switch (owner.getKind()) { case METHOD: - return handleMethod(annotationNode, (JCMethodDecl)owner.get(), exceptions); + handleMethod(annotationNode, (JCMethodDecl)owner.get(), exceptions); + break; default: annotationNode.addError("@SneakyThrows is legal only on methods and constructors."); - return true; + break; } } - private boolean handleMethod(JavacNode annotation, JCMethodDecl method, Collection<String> exceptions) { + private void handleMethod(JavacNode annotation, JCMethodDecl method, Collection<String> exceptions) { JavacNode methodNode = annotation.up(); if ( (method.mods.flags & Flags.ABSTRACT) != 0) { annotation.addError("@SneakyThrows can only be used on concrete methods."); - return true; + return; } - if (method.body == null) return false; + if (method.body == null) return; List<JCStatement> contents = method.body.stats; for (String exception : exceptions) { - contents = List.of(buildTryCatchBlock(methodNode, contents, exception)); + contents = List.of(buildTryCatchBlock(methodNode, contents, exception, annotation.get())); } method.body.stats = contents; methodNode.rebuild(); - - return true; } - private JCStatement buildTryCatchBlock(JavacNode node, List<JCStatement> contents, String exception) { + private JCStatement buildTryCatchBlock(JavacNode node, List<JCStatement> contents, String exception, JCTree source) { TreeMaker maker = node.getTreeMaker(); - JCBlock tryBlock = maker.Block(0, contents); + JCBlock tryBlock = Javac.setGeneratedBy(maker.Block(0, contents), source); JCExpression varType = chainDots(maker, node, exception.split("\\.")); @@ -108,7 +109,7 @@ public class HandleSneakyThrows implements JavacAnnotationHandler<SneakyThrows> List.<JCExpression>nil(), lombokLombokSneakyThrowNameRef, List.<JCExpression>of(maker.Ident(node.toName("$ex"))))))); - return maker.Try(tryBlock, List.of(maker.Catch(catchParam, catchBody)), null); + return Javac.setGeneratedBy(maker.Try(tryBlock, List.of(Javac.recursiveSetGeneratedBy(maker.Catch(catchParam, catchBody), source)), null), source); } @Override public boolean isResolutionBased() { diff --git a/src/core/lombok/javac/handlers/HandleSynchronized.java b/src/core/lombok/javac/handlers/HandleSynchronized.java index 42e29239..c8e9e79d 100644 --- a/src/core/lombok/javac/handlers/HandleSynchronized.java +++ b/src/core/lombok/javac/handlers/HandleSynchronized.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,14 +51,14 @@ public class HandleSynchronized implements JavacAnnotationHandler<Synchronized> private static final String INSTANCE_LOCK_NAME = "$lock"; private static final String STATIC_LOCK_NAME = "$LOCK"; - @Override public boolean handle(AnnotationValues<Synchronized> annotation, JCAnnotation ast, JavacNode annotationNode) { - markAnnotationAsProcessed(annotationNode, Synchronized.class); + @Override public void handle(AnnotationValues<Synchronized> annotation, JCAnnotation ast, JavacNode annotationNode) { + deleteAnnotationIfNeccessary(annotationNode, Synchronized.class); JavacNode methodNode = annotationNode.up(); if (methodNode == null || methodNode.getKind() != Kind.METHOD || !(methodNode.get() instanceof JCMethodDecl)) { annotationNode.addError("@Synchronized is legal only on methods."); - return true; + return; } JCMethodDecl method = (JCMethodDecl)methodNode.get(); @@ -66,7 +66,7 @@ public class HandleSynchronized implements JavacAnnotationHandler<Synchronized> if ((method.mods.flags & Flags.ABSTRACT) != 0) { annotationNode.addError("@Synchronized is legal only on concrete methods."); - return true; + return; } boolean isStatic = (method.mods.flags & Flags.STATIC) != 0; String lockName = annotation.getInstance().value(); @@ -81,19 +81,19 @@ public class HandleSynchronized implements JavacAnnotationHandler<Synchronized> if (fieldExists(lockName, methodNode) == MemberExistsResult.NOT_EXISTS) { if (!autoMake) { annotationNode.addError("The field " + lockName + " does not exist."); - return true; + return; } JCExpression objectType = chainDots(maker, methodNode, "java", "lang", "Object"); - //We use 'new Object[0];' because quite unlike 'new Object();', empty arrays *ARE* serializable! + //We use 'new Object[0];' because unlike 'new Object();', empty arrays *ARE* serializable! JCNewArray newObjectArray = maker.NewArray(chainDots(maker, methodNode, "java", "lang", "Object"), List.<JCExpression>of(maker.Literal(Javac.getCTCint(TypeTags.class, "INT"), 0)), null); - JCVariableDecl fieldDecl = maker.VarDef( + JCVariableDecl fieldDecl = Javac.recursiveSetGeneratedBy(maker.VarDef( maker.Modifiers(Flags.PRIVATE | Flags.FINAL | (isStatic ? Flags.STATIC : 0)), - methodNode.toName(lockName), objectType, newObjectArray); + methodNode.toName(lockName), objectType, newObjectArray), ast); injectFieldSuppressWarnings(methodNode.up(), fieldDecl); } - if (method.body == null) return false; + if (method.body == null) return; JCExpression lockNode; if (isStatic) { @@ -102,11 +102,10 @@ public class HandleSynchronized implements JavacAnnotationHandler<Synchronized> lockNode = maker.Select(maker.Ident(methodNode.toName("this")), methodNode.toName(lockName)); } - method.body = maker.Block(0, List.<JCStatement>of(maker.Synchronized(lockNode, method.body))); + Javac.recursiveSetGeneratedBy(lockNode, ast); + method.body = Javac.setGeneratedBy(maker.Block(0, List.<JCStatement>of(Javac.setGeneratedBy(maker.Synchronized(lockNode, method.body), ast))), ast); methodNode.rebuild(); - - return true; } @Override public boolean isResolutionBased() { diff --git a/src/core/lombok/javac/handlers/HandleToString.java b/src/core/lombok/javac/handlers/HandleToString.java index 8bc8036f..48fc90dc 100644 --- a/src/core/lombok/javac/handlers/HandleToString.java +++ b/src/core/lombok/javac/handlers/HandleToString.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 @@ -69,8 +69,8 @@ public class HandleToString implements JavacAnnotationHandler<ToString> { } } - @Override public boolean handle(AnnotationValues<ToString> annotation, JCAnnotation ast, JavacNode annotationNode) { - markAnnotationAsProcessed(annotationNode, ToString.class); + @Override public void handle(AnnotationValues<ToString> annotation, JCAnnotation ast, JavacNode annotationNode) { + deleteAnnotationIfNeccessary(annotationNode, ToString.class); ToString ann = annotation.getInstance(); List<String> excludes = List.from(ann.exclude()); @@ -92,7 +92,7 @@ public class HandleToString implements JavacAnnotationHandler<ToString> { FieldAccess fieldAccess = ann.doNotUseGetters() ? FieldAccess.PREFER_FIELD : FieldAccess.GETTER; - return generateToString(typeNode, annotationNode, excludes, includes, ann.includeFieldNames(), callSuper, true, fieldAccess); + generateToString(typeNode, annotationNode, excludes, includes, ann.includeFieldNames(), callSuper, true, fieldAccess); } public void generateToStringForType(JavacNode typeNode, JavacNode errorNode) { @@ -112,7 +112,7 @@ public class HandleToString implements JavacAnnotationHandler<ToString> { generateToString(typeNode, errorNode, null, null, includeFieldNames, null, false, FieldAccess.GETTER); } - private boolean generateToString(JavacNode typeNode, JavacNode errorNode, List<String> excludes, List<String> includes, + private void generateToString(JavacNode typeNode, JavacNode source, List<String> excludes, List<String> includes, boolean includeFieldNames, Boolean callSuper, boolean whineIfExists, FieldAccess fieldAccess) { boolean notAClass = true; if (typeNode.get() instanceof JCClassDecl) { @@ -127,8 +127,8 @@ public class HandleToString implements JavacAnnotationHandler<ToString> { } if (notAClass) { - errorNode.addError("@ToString is only supported on a class or enum."); - return false; + source.addError("@ToString is only supported on a class or enum."); + return; } ListBuffer<JavacNode> nodesForToString = ListBuffer.lb(); @@ -154,22 +154,21 @@ public class HandleToString implements JavacAnnotationHandler<ToString> { switch (methodExists("toString", typeNode)) { case NOT_EXISTS: - JCMethodDecl method = createToString(typeNode, nodesForToString.toList(), includeFieldNames, callSuper, fieldAccess); + JCMethodDecl method = createToString(typeNode, nodesForToString.toList(), includeFieldNames, callSuper, fieldAccess, source.get()); injectMethod(typeNode, method); - return true; + break; case EXISTS_BY_LOMBOK: - return true; + break; default: case EXISTS_BY_USER: if (whineIfExists) { - errorNode.addWarning("Not generating toString(): A method with that name already exists"); + source.addWarning("Not generating toString(): A method with that name already exists"); } - return true; + break; } - } - private JCMethodDecl createToString(JavacNode typeNode, List<JavacNode> fields, boolean includeFieldNames, boolean callSuper, FieldAccess fieldAccess) { + private JCMethodDecl createToString(JavacNode typeNode, List<JavacNode> fields, boolean includeFieldNames, boolean callSuper, FieldAccess fieldAccess, JCTree source) { TreeMaker maker = typeNode.getTreeMaker(); JCAnnotation overrideAnnotation = maker.Annotation(chainDots(maker, typeNode, "java", "lang", "Override"), List.<JCExpression>nil()); @@ -238,8 +237,8 @@ public class HandleToString implements JavacAnnotationHandler<ToString> { JCBlock body = maker.Block(0, List.of(returnStatement)); - return maker.MethodDef(mods, typeNode.toName("toString"), returnType, - List.<JCTypeParameter>nil(), List.<JCVariableDecl>nil(), List.<JCExpression>nil(), body, null); + return Javac.recursiveSetGeneratedBy(maker.MethodDef(mods, typeNode.toName("toString"), returnType, + List.<JCTypeParameter>nil(), List.<JCVariableDecl>nil(), List.<JCExpression>nil(), body, null), source); } private String getTypeName(JavacNode typeNode) { diff --git a/src/core/lombok/javac/handlers/HandleVal.java b/src/core/lombok/javac/handlers/HandleVal.java index b21137f7..4dafa360 100644 --- a/src/core/lombok/javac/handlers/HandleVal.java +++ b/src/core/lombok/javac/handlers/HandleVal.java @@ -1,5 +1,5 @@ /* - * Copyright © 2010 Reinier Zwitserloot, Roel Spilker and Robbert Jan Grootjans. + * Copyright © 2010-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 @@ -49,6 +49,8 @@ public class HandleVal extends JavacASTAdapter { @Override public void visitLocal(JavacNode localNode, JCVariableDecl local) { if (local.vartype == null || (!local.vartype.toString().equals("val") && !local.vartype.toString().equals("lombok.val"))) return; + JCTree source = local.vartype; + if (!Javac.typeMatches(val.class, localNode, local.vartype)) return; JCExpression rhsOfEnhancedForLoop = null; @@ -75,7 +77,7 @@ public class HandleVal extends JavacASTAdapter { local.mods.flags |= Flags.FINAL; if (!localNode.shouldDeleteLombokAnnotations()) { - JCAnnotation valAnnotation = localNode.getTreeMaker().Annotation(local.vartype, List.<JCExpression>nil()); + JCAnnotation valAnnotation = Javac.recursiveSetGeneratedBy(localNode.getTreeMaker().Annotation(local.vartype, List.<JCExpression>nil()), source); local.mods.annotations = local.mods.annotations == null ? List.of(valAnnotation) : local.mods.annotations.append(valAnnotation); } @@ -118,11 +120,13 @@ public class HandleVal extends JavacASTAdapter { localNode.getAst().setChanged(); } catch (JavacResolution.TypeNotConvertibleException e) { localNode.addError("Cannot use 'val' here because initializer expression does not have a representable type: " + e.getMessage()); - local.vartype = JavacResolution.createJavaLangObject(localNode.getTreeMaker(), localNode.getAst());; + local.vartype = JavacResolution.createJavaLangObject(localNode.getTreeMaker(), localNode.getAst()); } } catch (RuntimeException e) { - local.vartype = JavacResolution.createJavaLangObject(localNode.getTreeMaker(), localNode.getAst());; + local.vartype = JavacResolution.createJavaLangObject(localNode.getTreeMaker(), localNode.getAst()); throw e; + } finally { + Javac.recursiveSetGeneratedBy(local.vartype, source); } } } diff --git a/src/core/lombok/javac/handlers/JavacHandlerUtil.java b/src/core/lombok/javac/handlers/JavacHandlerUtil.java index 1fb72dfa..1f0da79a 100644 --- a/src/core/lombok/javac/handlers/JavacHandlerUtil.java +++ b/src/core/lombok/javac/handlers/JavacHandlerUtil.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 @@ -78,7 +78,7 @@ public class JavacHandlerUtil { * then removes any import statement that imports this exact annotation (not star imports). * Only does this if the DeleteLombokAnnotations class is in the context. */ - public static void markAnnotationAsProcessed(JavacNode annotation, Class<? extends Annotation> annotationType) { + public static void deleteAnnotationIfNeccessary(JavacNode annotation, Class<? extends Annotation> annotationType) { if (!annotation.shouldDeleteLombokAnnotations()) return; JavacNode parentNode = annotation.directUp(); switch (parentNode.getKind()) { @@ -203,9 +203,7 @@ public class JavacHandlerUtil { for (JCTree def : ((JCClassDecl)node.get()).defs) { if (def instanceof JCVariableDecl) { if (((JCVariableDecl)def).name.contentEquals(fieldName)) { - JavacNode existing = node.getNodeFor(def); - if (existing == null || !existing.isHandled()) return MemberExistsResult.EXISTS_BY_USER; - return MemberExistsResult.EXISTS_BY_LOMBOK; + return Javac.getGeneratedBy(def) == null ? MemberExistsResult.EXISTS_BY_USER : MemberExistsResult.EXISTS_BY_LOMBOK; } } } @@ -236,11 +234,7 @@ public class JavacHandlerUtil { if (def instanceof JCMethodDecl) { String name = ((JCMethodDecl)def).name.toString(); boolean matches = caseSensitive ? name.equals(methodName) : name.equalsIgnoreCase(methodName); - if (matches) { - JavacNode existing = node.getNodeFor(def); - if (existing == null || !existing.isHandled()) return MemberExistsResult.EXISTS_BY_USER; - return MemberExistsResult.EXISTS_BY_LOMBOK; - } + if (matches) return Javac.getGeneratedBy(def) == null ? MemberExistsResult.EXISTS_BY_USER : MemberExistsResult.EXISTS_BY_LOMBOK; } } } @@ -264,9 +258,7 @@ public class JavacHandlerUtil { if (def instanceof JCMethodDecl) { if (((JCMethodDecl)def).name.contentEquals("<init>")) { if ((((JCMethodDecl)def).mods.flags & Flags.GENERATEDCONSTR) != 0) continue; - JavacNode existing = node.getNodeFor(def); - if (existing == null || !existing.isHandled()) return MemberExistsResult.EXISTS_BY_USER; - return MemberExistsResult.EXISTS_BY_LOMBOK; + return Javac.getGeneratedBy(def) == null ? MemberExistsResult.EXISTS_BY_USER : MemberExistsResult.EXISTS_BY_LOMBOK; } } } @@ -448,10 +440,10 @@ public class JavacHandlerUtil { private static void injectField(JavacNode typeNode, JCVariableDecl field, boolean addSuppressWarnings) { JCClassDecl type = (JCClassDecl) typeNode.get(); - if (addSuppressWarnings) addSuppressWarningsAll(field.mods, typeNode, field.pos); + if (addSuppressWarnings) addSuppressWarningsAll(field.mods, typeNode, field.pos, Javac.getGeneratedBy(field)); type.defs = type.defs.append(field); - typeNode.add(field, Kind.FIELD).recursiveSetHandled(); + typeNode.add(field, Kind.FIELD); } /** @@ -479,19 +471,19 @@ public class JavacHandlerUtil { } } - addSuppressWarningsAll(method.mods, typeNode, method.pos); + addSuppressWarningsAll(method.mods, typeNode, method.pos, Javac.getGeneratedBy(method)); type.defs = type.defs.append(method); - typeNode.add(method, Kind.METHOD).recursiveSetHandled(); + typeNode.add(method, Kind.METHOD); } - private static void addSuppressWarningsAll(JCModifiers mods, JavacNode node, int pos) { + private static void addSuppressWarningsAll(JCModifiers mods, JavacNode node, int pos, JCTree source) { TreeMaker maker = node.getTreeMaker(); JCExpression suppressWarningsType = chainDots(maker, node, "java", "lang", "SuppressWarnings"); JCLiteral allLiteral = maker.Literal("all"); suppressWarningsType.pos = pos; allLiteral.pos = pos; - JCAnnotation annotation = maker.Annotation(suppressWarningsType, List.<JCExpression>of(allLiteral)); + JCAnnotation annotation = Javac.recursiveSetGeneratedBy(maker.Annotation(suppressWarningsType, List.<JCExpression>of(allLiteral)), source); annotation.pos = pos; mods.annotations = mods.annotations.append(annotation); } |