diff options
Diffstat (limited to 'src')
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); } |