diff options
author | Reinier Zwitserloot <reinier@zwitserloot.com> | 2013-02-11 22:34:48 +0100 |
---|---|---|
committer | Reinier Zwitserloot <reinier@zwitserloot.com> | 2013-02-11 22:34:48 +0100 |
commit | aafd83079a3000d3deb6e40a182849da2509fbfb (patch) | |
tree | cf87951eee9bb098bb96ecc3c02c6f1ab34c405d /src/core/lombok/javac/handlers | |
parent | ef8769d3180b2c6de91a64f69dfa23a2e6e449b9 (diff) | |
download | lombok-aafd83079a3000d3deb6e40a182849da2509fbfb.tar.gz lombok-aafd83079a3000d3deb6e40a182849da2509fbfb.tar.bz2 lombok-aafd83079a3000d3deb6e40a182849da2509fbfb.zip |
BIG commit:
* re-introduction of onMethod/onConstructor/onParam
* tests checking error/warnings rewritten to be more heuristic, in order to accomodate difference in messaging between java6 and java 7
* Ability to eliminate java's own output of erroneous error messages (heh); i.e. those messages that are invalidated by lombok's actions. This mechanism is used for onMethod/onConstructor/onParam
* First steps to unifying a billion setGeneratedBy calls into a single visitor traversal for eclipse' HandleGetter/Setter/Constructor/Wither
* To simplify 'zooming in' the tests on just a few files, added an 'accept' mechanism.
* Updated copyright headers of website to 2013.
Diffstat (limited to 'src/core/lombok/javac/handlers')
-rw-r--r-- | src/core/lombok/javac/handlers/HandleConstructor.java | 23 | ||||
-rw-r--r-- | src/core/lombok/javac/handlers/HandleGetter.java | 32 | ||||
-rw-r--r-- | src/core/lombok/javac/handlers/HandleSetter.java | 29 | ||||
-rw-r--r-- | src/core/lombok/javac/handlers/HandleWither.java | 38 | ||||
-rw-r--r-- | src/core/lombok/javac/handlers/JavacHandlerUtil.java | 70 |
5 files changed, 124 insertions, 68 deletions
diff --git a/src/core/lombok/javac/handlers/HandleConstructor.java b/src/core/lombok/javac/handlers/HandleConstructor.java index b6c31f83..bb883ca4 100644 --- a/src/core/lombok/javac/handlers/HandleConstructor.java +++ b/src/core/lombok/javac/handlers/HandleConstructor.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2011 The Project Lombok Authors. + * Copyright (C) 2010-2013 The Project Lombok Authors. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -60,12 +60,13 @@ public class HandleConstructor { deleteImportFromCompilationUnit(annotationNode, "lombok.AccessLevel"); JavacNode typeNode = annotationNode.up(); if (!checkLegality(typeNode, annotationNode, NoArgsConstructor.class.getSimpleName())) return; + List<JCAnnotation> onConstructor = unboxAndRemoveAnnotationParameter(ast, "onConstructor", "@NoArgsConstructor(onConstructor=", annotationNode); NoArgsConstructor ann = annotation.getInstance(); AccessLevel level = ann.access(); String staticName = ann.staticName(); if (level == AccessLevel.NONE) return; List<JavacNode> fields = List.nil(); - new HandleConstructor().generateConstructor(typeNode, level, fields, staticName, false, false, annotationNode); + new HandleConstructor().generateConstructor(typeNode, level, onConstructor, fields, staticName, false, false, annotationNode); } } @@ -76,13 +77,14 @@ public class HandleConstructor { deleteImportFromCompilationUnit(annotationNode, "lombok.AccessLevel"); JavacNode typeNode = annotationNode.up(); if (!checkLegality(typeNode, annotationNode, RequiredArgsConstructor.class.getSimpleName())) return; + List<JCAnnotation> onConstructor = unboxAndRemoveAnnotationParameter(ast, "onConstructor", "@RequiredArgsConstructor(onConstructor=", annotationNode); RequiredArgsConstructor ann = annotation.getInstance(); AccessLevel level = ann.access(); String staticName = ann.staticName(); @SuppressWarnings("deprecation") boolean suppressConstructorProperties = ann.suppressConstructorProperties(); if (level == AccessLevel.NONE) return; - new HandleConstructor().generateConstructor(typeNode, level, findRequiredFields(typeNode), staticName, false, suppressConstructorProperties, annotationNode); + new HandleConstructor().generateConstructor(typeNode, level, onConstructor, findRequiredFields(typeNode), staticName, false, suppressConstructorProperties, annotationNode); } } @@ -110,13 +112,14 @@ public class HandleConstructor { deleteImportFromCompilationUnit(annotationNode, "lombok.AccessLevel"); JavacNode typeNode = annotationNode.up(); if (!checkLegality(typeNode, annotationNode, AllArgsConstructor.class.getSimpleName())) return; + List<JCAnnotation> onConstructor = unboxAndRemoveAnnotationParameter(ast, "onConstructor", "@AllArgsConstructor(onConstructor=", annotationNode); AllArgsConstructor ann = annotation.getInstance(); AccessLevel level = ann.access(); String staticName = ann.staticName(); @SuppressWarnings("deprecation") boolean suppressConstructorProperties = ann.suppressConstructorProperties(); if (level == AccessLevel.NONE) return; - new HandleConstructor().generateConstructor(typeNode, level, findAllFields(typeNode), staticName, false, suppressConstructorProperties, annotationNode); + new HandleConstructor().generateConstructor(typeNode, level, onConstructor, findAllFields(typeNode), staticName, false, suppressConstructorProperties, annotationNode); } } @@ -152,14 +155,14 @@ public class HandleConstructor { } public void generateRequiredArgsConstructor(JavacNode typeNode, AccessLevel level, String staticName, boolean skipIfConstructorExists, JavacNode source) { - generateConstructor(typeNode, level, findRequiredFields(typeNode), staticName, skipIfConstructorExists, false, source); + generateConstructor(typeNode, level, List.<JCAnnotation>nil(), findRequiredFields(typeNode), staticName, skipIfConstructorExists, false, source); } public void generateAllArgsConstructor(JavacNode typeNode, AccessLevel level, String staticName, boolean skipIfConstructorExists, JavacNode source) { - generateConstructor(typeNode, level, findAllFields(typeNode), staticName, skipIfConstructorExists, false, source); + generateConstructor(typeNode, level, List.<JCAnnotation>nil(), findAllFields(typeNode), staticName, skipIfConstructorExists, false, source); } - public void generateConstructor(JavacNode typeNode, AccessLevel level, List<JavacNode> fields, String staticName, boolean skipIfConstructorExists, boolean suppressConstructorProperties, JavacNode source) { + public void generateConstructor(JavacNode typeNode, AccessLevel level, List<JCAnnotation> onConstructor, List<JavacNode> fields, String staticName, boolean skipIfConstructorExists, boolean suppressConstructorProperties, JavacNode source) { boolean staticConstrRequired = staticName != null && !staticName.equals(""); if (skipIfConstructorExists && constructorExists(typeNode) != MemberExistsResult.NOT_EXISTS) return; @@ -183,7 +186,7 @@ public class HandleConstructor { } } - JCMethodDecl constr = createConstructor(staticConstrRequired ? AccessLevel.PRIVATE : level, typeNode, fields, suppressConstructorProperties, source.get()); + JCMethodDecl constr = createConstructor(staticConstrRequired ? AccessLevel.PRIVATE : level, onConstructor, typeNode, fields, suppressConstructorProperties, source.get()); injectMethod(typeNode, constr); if (staticConstrRequired) { JCMethodDecl staticConstr = createStaticConstructor(staticName, level, typeNode, fields, source.get()); @@ -204,7 +207,7 @@ public class HandleConstructor { mods.annotations = mods.annotations.append(annotation); } - private JCMethodDecl createConstructor(AccessLevel level, JavacNode typeNode, List<JavacNode> fields, boolean suppressConstructorProperties, JCTree source) { + private JCMethodDecl createConstructor(AccessLevel level, List<JCAnnotation> onConstructor, JavacNode typeNode, List<JavacNode> fields, boolean suppressConstructorProperties, JCTree source) { TreeMaker maker = typeNode.getTreeMaker(); boolean isEnum = (((JCClassDecl) typeNode.get()).mods.flags & Flags.ENUM) != 0; @@ -234,6 +237,8 @@ public class HandleConstructor { if (!suppressConstructorProperties && level != AccessLevel.PRIVATE && !isLocalType(typeNode)) { addConstructorProperties(mods, typeNode, fields); } + if (onConstructor != null) mods.annotations = mods.annotations.appendList(copyAnnotations(onConstructor)); + return 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); } diff --git a/src/core/lombok/javac/handlers/HandleGetter.java b/src/core/lombok/javac/handlers/HandleGetter.java index 65947c72..bc68d5ad 100644 --- a/src/core/lombok/javac/handlers/HandleGetter.java +++ b/src/core/lombok/javac/handlers/HandleGetter.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009-2012 The Project Lombok Authors. + * Copyright (C) 2009-2013 The Project Lombok Authors. * * 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,8 +21,8 @@ */ package lombok.javac.handlers; -import static lombok.javac.handlers.JavacHandlerUtil.*; import static lombok.javac.Javac.*; +import static lombok.javac.handlers.JavacHandlerUtil.*; import java.util.Collection; import java.util.Collections; @@ -32,9 +32,9 @@ import java.util.Map; import lombok.AccessLevel; import lombok.Delegate; import lombok.Getter; +import lombok.core.AST.Kind; import lombok.core.AnnotationValues; import lombok.core.TransformationsUtil; -import lombok.core.AST.Kind; import lombok.javac.JavacAnnotationHandler; import lombok.javac.JavacNode; import lombok.javac.handlers.JavacHandlerUtil.FieldAccess; @@ -43,7 +43,6 @@ 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.JCBinary; import com.sun.tools.javac.tree.JCTree.JCBlock; @@ -60,10 +59,11 @@ import com.sun.tools.javac.tree.JCTree.JCSynchronized; import com.sun.tools.javac.tree.JCTree.JCTypeApply; import com.sun.tools.javac.tree.JCTree.JCTypeParameter; import com.sun.tools.javac.tree.JCTree.JCVariableDecl; +import com.sun.tools.javac.tree.TreeMaker; +import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.ListBuffer; import com.sun.tools.javac.util.Name; -import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; /** * Handles the {@code lombok.Getter} annotation for javac. @@ -123,8 +123,7 @@ public class HandleGetter extends JavacAnnotationHandler<Getter> { //The annotation will make it happen, so we can skip it. return; } - - createGetterForField(level, fieldNode, fieldNode, false, lazy); + createGetterForField(level, fieldNode, fieldNode, false, lazy, List.<JCAnnotation>nil()); } @Override public void handle(AnnotationValues<Getter> annotation, JCAnnotation ast, JavacNode annotationNode) { @@ -144,25 +143,30 @@ public class HandleGetter extends JavacAnnotationHandler<Getter> { if (node == null) return; + List<JCAnnotation> onMethod = unboxAndRemoveAnnotationParameter(ast, "onMethod", "@Getter(onMethod=", annotationNode); + switch (node.getKind()) { case FIELD: - createGetterForFields(level, fields, annotationNode, true, lazy); + createGetterForFields(level, fields, annotationNode, true, lazy, onMethod); 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."); generateGetterForType(node, annotationNode, level, false); break; } } - private void createGetterForFields(AccessLevel level, Collection<JavacNode> fieldNodes, JavacNode errorNode, boolean whineIfExists, boolean lazy) { + private void createGetterForFields(AccessLevel level, Collection<JavacNode> fieldNodes, JavacNode errorNode, boolean whineIfExists, boolean lazy, List<JCAnnotation> onMethod) { for (JavacNode fieldNode : fieldNodes) { - createGetterForField(level, fieldNode, errorNode, whineIfExists, lazy); + createGetterForField(level, fieldNode, errorNode, whineIfExists, lazy, onMethod); } } private void createGetterForField(AccessLevel level, - JavacNode fieldNode, JavacNode source, boolean whineIfExists, boolean lazy) { + JavacNode fieldNode, JavacNode source, boolean whineIfExists, boolean lazy, List<JCAnnotation> onMethod) { if (fieldNode.getKind() != Kind.FIELD) { source.addError("@Getter is only supported on a class or a field."); return; @@ -208,10 +212,10 @@ public class HandleGetter extends JavacAnnotationHandler<Getter> { long access = toJavacModifier(level) | (fieldDecl.mods.flags & Flags.STATIC); - injectMethod(fieldNode.up(), createGetter(access, fieldNode, fieldNode.getTreeMaker(), lazy, source.get())); + injectMethod(fieldNode.up(), createGetter(access, fieldNode, fieldNode.getTreeMaker(), source.get(), lazy, onMethod)); } - private JCMethodDecl createGetter(long access, JavacNode field, TreeMaker treeMaker, boolean lazy, JCTree source) { + private JCMethodDecl createGetter(long access, JavacNode field, TreeMaker treeMaker, JCTree source, boolean lazy, List<JCAnnotation> onMethod) { JCVariableDecl fieldNode = (JCVariableDecl) field.get(); // Remember the type; lazy will change it @@ -240,7 +244,7 @@ public class HandleGetter extends JavacAnnotationHandler<Getter> { List<JCAnnotation> delegates = findDelegatesAndRemoveFromField(field); - List<JCAnnotation> annsOnMethod = nonNulls.appendList(nullables); + List<JCAnnotation> annsOnMethod = copyAnnotations(onMethod).appendList(nonNulls).appendList(nullables); if (isFieldDeprecated(field)) { annsOnMethod = annsOnMethod.prepend(treeMaker.Annotation(chainDots(field, "java", "lang", "Deprecated"), List.<JCExpression>nil())); } diff --git a/src/core/lombok/javac/handlers/HandleSetter.java b/src/core/lombok/javac/handlers/HandleSetter.java index e2c75e2e..c1e03c35 100644 --- a/src/core/lombok/javac/handlers/HandleSetter.java +++ b/src/core/lombok/javac/handlers/HandleSetter.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009-2012 The Project Lombok Authors. + * Copyright (C) 2009-2013 The Project Lombok Authors. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -118,7 +118,7 @@ public class HandleSetter extends JavacAnnotationHandler<Setter> { return; } - createSetterForField(level, fieldNode, fieldNode, false); + createSetterForField(level, fieldNode, fieldNode, false, List.<JCAnnotation>nil(), List.<JCAnnotation>nil()); } @Override public void handle(AnnotationValues<Setter> annotation, JCAnnotation ast, JavacNode annotationNode) { @@ -130,26 +130,28 @@ public class HandleSetter extends JavacAnnotationHandler<Setter> { if (level == AccessLevel.NONE || node == null) return; + List<JCAnnotation> onMethod = unboxAndRemoveAnnotationParameter(ast, "onMethod", "@Setter(onMethod=", annotationNode); + List<JCAnnotation> onParam = unboxAndRemoveAnnotationParameter(ast, "onParam", "@Setter(onParam=", annotationNode); + switch (node.getKind()) { case FIELD: - createSetterForFields(level, fields, annotationNode, true); + createSetterForFields(level, fields, annotationNode, true, onMethod, onParam); break; case TYPE: + if (!onMethod.isEmpty()) annotationNode.addError("'onMethod' is not supported for @Setter on a type."); + if (!onParam.isEmpty()) annotationNode.addError("'onParam' is not supported for @Setter on a type."); generateSetterForType(node, annotationNode, level, false); break; } } - private void createSetterForFields(AccessLevel level, Collection<JavacNode> fieldNodes, JavacNode errorNode, boolean whineIfExists) { - + private void createSetterForFields(AccessLevel level, Collection<JavacNode> fieldNodes, JavacNode errorNode, boolean whineIfExists, List<JCAnnotation> onMethod, List<JCAnnotation> onParam) { for (JavacNode fieldNode : fieldNodes) { - createSetterForField(level, fieldNode, errorNode, whineIfExists); + createSetterForField(level, fieldNode, errorNode, whineIfExists, onMethod, onParam); } } - private void createSetterForField(AccessLevel level, - JavacNode fieldNode, JavacNode source, boolean whineIfExists) { - + private void createSetterForField(AccessLevel level, JavacNode fieldNode, JavacNode source, boolean whineIfExists, List<JCAnnotation> onMethod, List<JCAnnotation> onParam) { if (fieldNode.getKind() != Kind.FIELD) { fieldNode.addError("@Setter is only supported on a class or a field."); return; @@ -188,11 +190,11 @@ public class HandleSetter extends JavacAnnotationHandler<Setter> { long access = toJavacModifier(level) | (fieldDecl.mods.flags & Flags.STATIC); - JCMethodDecl createdSetter = createSetter(access, fieldNode, fieldNode.getTreeMaker(), source.get()); + JCMethodDecl createdSetter = createSetter(access, fieldNode, fieldNode.getTreeMaker(), source.get(), onMethod, onParam); injectMethod(fieldNode.up(), createdSetter); } - private JCMethodDecl createSetter(long access, JavacNode field, TreeMaker treeMaker, JCTree source) { + private JCMethodDecl createSetter(long access, JavacNode field, TreeMaker treeMaker, JCTree source, List<JCAnnotation> onMethod, List<JCAnnotation> onParam) { String setterName = toSetterName(field); boolean returnThis = shouldReturnThis(field); if (setterName == null) return null; @@ -207,7 +209,7 @@ public class HandleSetter extends JavacAnnotationHandler<Setter> { List<JCAnnotation> nullables = findAnnotations(field, TransformationsUtil.NULLABLE_PATTERN); Name methodName = field.toName(setterName); - List<JCAnnotation> annsOnParam = nonNulls.appendList(nullables); + List<JCAnnotation> annsOnParam = copyAnnotations(onParam).appendList(nonNulls).appendList(nullables); JCVariableDecl param = treeMaker.VarDef(treeMaker.Modifiers(Flags.FINAL, annsOnParam), fieldDecl.name, fieldDecl.vartype, null); @@ -241,10 +243,11 @@ public class HandleSetter extends JavacAnnotationHandler<Setter> { List<JCExpression> throwsClauses = List.nil(); JCExpression annotationMethodDefaultValue = null; - List<JCAnnotation> annsOnMethod = List.nil(); + List<JCAnnotation> annsOnMethod = copyAnnotations(onMethod); if (isFieldDeprecated(field)) { annsOnMethod = annsOnMethod.prepend(treeMaker.Annotation(chainDots(field, "java", "lang", "Deprecated"), List.<JCExpression>nil())); } + return recursiveSetGeneratedBy(treeMaker.MethodDef(treeMaker.Modifiers(access, annsOnMethod), methodName, methodType, methodGenericParams, parameters, throwsClauses, methodBody, annotationMethodDefaultValue), source); } diff --git a/src/core/lombok/javac/handlers/HandleWither.java b/src/core/lombok/javac/handlers/HandleWither.java index 64011f91..ba5aa72d 100644 --- a/src/core/lombok/javac/handlers/HandleWither.java +++ b/src/core/lombok/javac/handlers/HandleWither.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 The Project Lombok Authors. + * Copyright (C) 2012-2013 The Project Lombok Authors. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -109,16 +109,12 @@ public class HandleWither extends JavacAnnotationHandler<Wither> { * @param pos The node responsible for generating the wither (the {@code @Value} or {@code @Wither} annotation). */ public void generateWitherForField(JavacNode fieldNode, DiagnosticPosition pos, AccessLevel level) { - for (JavacNode child : fieldNode.down()) { - if (child.getKind() == Kind.ANNOTATION) { - if (annotationTypeMatches(Wither.class, child)) { - //The annotation will make it happen, so we can skip it. - return; - } - } + if (hasAnnotation(Wither.class, fieldNode)) { + //The annotation will make it happen, so we can skip it. + return; } - createWitherForField(level, fieldNode, fieldNode, false); + createWitherForField(level, fieldNode, fieldNode, false, List.<JCAnnotation>nil(), List.<JCAnnotation>nil()); } @Override public void handle(AnnotationValues<Wither> annotation, JCAnnotation ast, JavacNode annotationNode) { @@ -130,25 +126,28 @@ public class HandleWither extends JavacAnnotationHandler<Wither> { if (level == AccessLevel.NONE || node == null) return; + List<JCAnnotation> onMethod = unboxAndRemoveAnnotationParameter(ast, "onMethod", "@Setter(onMethod=", annotationNode); + List<JCAnnotation> onParam = unboxAndRemoveAnnotationParameter(ast, "onParam", "@Setter(onParam=", annotationNode); + switch (node.getKind()) { case FIELD: - createWitherForFields(level, fields, annotationNode, true); + createWitherForFields(level, fields, annotationNode, true, onMethod, onParam); break; case TYPE: + if (!onMethod.isEmpty()) annotationNode.addError("'onMethod' is not supported for @Wither on a type."); + if (!onParam.isEmpty()) annotationNode.addError("'onParam' is not supported for @Wither on a type."); generateWitherForType(node, annotationNode, level, false); break; } } - private void createWitherForFields(AccessLevel level, Collection<JavacNode> fieldNodes, JavacNode errorNode, boolean whineIfExists) { + private void createWitherForFields(AccessLevel level, Collection<JavacNode> fieldNodes, JavacNode errorNode, boolean whineIfExists, List<JCAnnotation> onMethod, List<JCAnnotation> onParam) { for (JavacNode fieldNode : fieldNodes) { - createWitherForField(level, fieldNode, errorNode, whineIfExists); + createWitherForField(level, fieldNode, errorNode, whineIfExists, onMethod, onParam); } } - private void createWitherForField(AccessLevel level, - JavacNode fieldNode, JavacNode source, boolean whineIfExists) { - + private void createWitherForField(AccessLevel level, JavacNode fieldNode, JavacNode source, boolean whineIfExists, List<JCAnnotation> onMethod, List<JCAnnotation> onParam) { if (fieldNode.getKind() != Kind.FIELD) { fieldNode.addError("@Wither is only supported on a class or a field."); return; @@ -197,11 +196,11 @@ public class HandleWither extends JavacAnnotationHandler<Wither> { long access = toJavacModifier(level); - JCMethodDecl createdWither = createWither(access, fieldNode, fieldNode.getTreeMaker(), source.get()); + JCMethodDecl createdWither = createWither(access, fieldNode, fieldNode.getTreeMaker(), source.get(), onMethod, onParam); injectMethod(fieldNode.up(), createdWither); } - private JCMethodDecl createWither(long access, JavacNode field, TreeMaker treeMaker, JCTree source) { + private JCMethodDecl createWither(long access, JavacNode field, TreeMaker treeMaker, JCTree source, List<JCAnnotation> onMethod, List<JCAnnotation> onParam) { String witherName = toWitherName(field); if (witherName == null) return null; @@ -212,7 +211,7 @@ public class HandleWither extends JavacAnnotationHandler<Wither> { List<JCAnnotation> nullables = findAnnotations(field, TransformationsUtil.NULLABLE_PATTERN); Name methodName = field.toName(witherName); - List<JCAnnotation> annsOnParam = nonNulls.appendList(nullables); + List<JCAnnotation> annsOnParam = copyAnnotations(onParam).appendList(nonNulls).appendList(nullables); JCVariableDecl param = treeMaker.VarDef(treeMaker.Modifiers(Flags.FINAL, annsOnParam), fieldDecl.name, fieldDecl.vartype, null); @@ -260,7 +259,8 @@ public class HandleWither extends JavacAnnotationHandler<Wither> { List<JCExpression> throwsClauses = List.nil(); JCExpression annotationMethodDefaultValue = null; - List<JCAnnotation> annsOnMethod = List.nil(); + List<JCAnnotation> annsOnMethod = copyAnnotations(onMethod); + if (isFieldDeprecated(field)) { annsOnMethod = annsOnMethod.prepend(treeMaker.Annotation(chainDots(field, "java", "lang", "Deprecated"), List.<JCExpression>nil())); } diff --git a/src/core/lombok/javac/handlers/JavacHandlerUtil.java b/src/core/lombok/javac/handlers/JavacHandlerUtil.java index ad3e4a17..c2de5b05 100644 --- a/src/core/lombok/javac/handlers/JavacHandlerUtil.java +++ b/src/core/lombok/javac/handlers/JavacHandlerUtil.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009-2012 The Project Lombok Authors. + * Copyright (C) 2009-2013 The Project Lombok Authors. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -63,8 +63,8 @@ import com.sun.tools.javac.tree.JCTree.JCModifiers; import com.sun.tools.javac.tree.JCTree.JCNewArray; import com.sun.tools.javac.tree.JCTree.JCPrimitiveTypeTree; import com.sun.tools.javac.tree.JCTree.JCStatement; -import com.sun.tools.javac.tree.JCTree.JCTypeParameter; import com.sun.tools.javac.tree.JCTree.JCTypeApply; +import com.sun.tools.javac.tree.JCTree.JCTypeParameter; import com.sun.tools.javac.tree.JCTree.JCVariableDecl; import com.sun.tools.javac.tree.JCTree.JCWildcard; import com.sun.tools.javac.tree.JCTree.TypeBoundKind; @@ -920,33 +920,77 @@ public class JavacHandlerUtil { return problematic.toList(); } - static List<JCExpression> getAndRemoveAnnotationParameter(JCAnnotation ast, String parameterName) { + static List<JCAnnotation> unboxAndRemoveAnnotationParameter(JCAnnotation ast, String parameterName, String errorName, JavacNode errorNode) { ListBuffer<JCExpression> params = ListBuffer.lb(); - List<JCExpression> result = List.nil(); + ListBuffer<JCAnnotation> result = ListBuffer.lb(); + errorNode.removeDeferredErrors(); + + outer: for (JCExpression param : ast.args) { + String nameOfParam = "value"; + JCExpression valueOfParam = null; if (param instanceof JCAssign) { JCAssign assign = (JCAssign) param; if (assign.lhs instanceof JCIdent) { JCIdent ident = (JCIdent) assign.lhs; - if (parameterName.equals(ident.name.toString())) { - if (assign.rhs instanceof JCNewArray) { - result = ((JCNewArray) assign.rhs).elems; + nameOfParam = ident.name.toString(); + } + valueOfParam = assign.rhs; + } + + if (!parameterName.equals(nameOfParam)) { + params.append(param); + continue outer; + } + + if (valueOfParam instanceof JCAnnotation) { + String dummyAnnotationName = ((JCAnnotation) valueOfParam).annotationType.toString(); + dummyAnnotationName = dummyAnnotationName.replace("_", ""); + if (dummyAnnotationName.length() > 0) { + errorNode.addError("The correct format is " + errorName + "@_({@SomeAnnotation, @SomeOtherAnnotation}))"); + continue outer; + } + for (JCExpression expr : ((JCAnnotation) valueOfParam).args) { + if (expr instanceof JCAssign && ((JCAssign) expr).lhs instanceof JCIdent) { + JCIdent id = (JCIdent) ((JCAssign) expr).lhs; + if ("value".equals(id.name.toString())) { + expr = ((JCAssign) expr).rhs; } else { - result = result.append(assign.rhs); + errorNode.addError("The correct format is " + errorName + "@_({@SomeAnnotation, @SomeOtherAnnotation}))"); + continue outer; } - continue; + } + + if (expr instanceof JCAnnotation) { + result.append((JCAnnotation) expr); + } else if (expr instanceof JCNewArray) { + for (JCExpression expr2 : ((JCNewArray) expr).elems) { + if (expr2 instanceof JCAnnotation) { + result.append((JCAnnotation) expr2); + } else { + errorNode.addError("The correct format is " + errorName + "@_({@SomeAnnotation, @SomeOtherAnnotation}))"); + continue outer; + } + } + } else { + errorNode.addError("The correct format is " + errorName + "@_({@SomeAnnotation, @SomeOtherAnnotation}))"); + continue outer; } } + } else { + if (valueOfParam instanceof JCNewArray && ((JCNewArray) valueOfParam).elems.isEmpty()) { + // Then we just remove it and move on (it's onMethod={} for example). + } else { + errorNode.addError("The correct format is " + errorName + "@_({@SomeAnnotation, @SomeOtherAnnotation}))"); + } } - - params.append(param); } ast.args = params.toList(); - return result; + return result.toList(); } - static List<JCAnnotation> copyAnnotations(List<JCExpression> in) { + static List<JCAnnotation> copyAnnotations(List<? extends JCExpression> in) { ListBuffer<JCAnnotation> out = ListBuffer.lb(); for (JCExpression expr : in) { if (!(expr instanceof JCAnnotation)) continue; |