aboutsummaryrefslogtreecommitdiff
path: root/src/core/lombok/eclipse
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/lombok/eclipse')
-rw-r--r--src/core/lombok/eclipse/EclipseAST.java3
-rw-r--r--src/core/lombok/eclipse/EclipseNode.java42
-rw-r--r--src/core/lombok/eclipse/TransformEclipseAST.java36
-rw-r--r--src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java144
-rwxr-xr-xsrc/core/lombok/eclipse/handlers/HandleBuilder.java29
-rwxr-xr-xsrc/core/lombok/eclipse/handlers/HandleConstructor.java10
-rw-r--r--src/core/lombok/eclipse/handlers/HandleFieldNameConstants.java12
-rw-r--r--src/core/lombok/eclipse/handlers/HandleGetter.java9
-rw-r--r--src/core/lombok/eclipse/handlers/HandleLog.java36
-rw-r--r--src/core/lombok/eclipse/handlers/HandleNonNull.java7
-rw-r--r--src/core/lombok/eclipse/handlers/HandleSuperBuilder.java73
-rw-r--r--src/core/lombok/eclipse/handlers/HandleUtilityClass.java2
-rwxr-xr-xsrc/core/lombok/eclipse/handlers/singulars/EclipseGuavaSingularizer.java12
-rwxr-xr-xsrc/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSetSingularizer.java12
-rwxr-xr-xsrc/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilMapSingularizer.java8
15 files changed, 323 insertions, 112 deletions
diff --git a/src/core/lombok/eclipse/EclipseAST.java b/src/core/lombok/eclipse/EclipseAST.java
index e724fb50..d53856af 100644
--- a/src/core/lombok/eclipse/EclipseAST.java
+++ b/src/core/lombok/eclipse/EclipseAST.java
@@ -318,6 +318,7 @@ public class EclipseAST extends AST<EclipseAST, EclipseNode, ASTNode> {
Field f = EcjReflectionCheck.typeReferenceAnnotations;
if (f == null) return null;
annss = (Annotation[][]) f.get(tr);
+ if (annss == null) return null;
return annss[annss.length - 1];
} catch (Throwable t) {
return null;
@@ -349,7 +350,7 @@ public class EclipseAST extends AST<EclipseAST, EclipseNode, ASTNode> {
if (!changed) clearChanged();
}
- private static boolean isComplete(CompilationUnitDeclaration unit) {
+ public static boolean isComplete(CompilationUnitDeclaration unit) {
return (unit.bits & ASTNode.HasAllMethodBodies) != 0;
}
diff --git a/src/core/lombok/eclipse/EclipseNode.java b/src/core/lombok/eclipse/EclipseNode.java
index 9db491f5..12e9ccdb 100644
--- a/src/core/lombok/eclipse/EclipseNode.java
+++ b/src/core/lombok/eclipse/EclipseNode.java
@@ -23,10 +23,6 @@ package lombok.eclipse;
import java.util.List;
-import lombok.core.AnnotationValues;
-import lombok.core.AST.Kind;
-import lombok.eclipse.handlers.EclipseHandlerUtil;
-
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.Annotation;
@@ -36,11 +32,16 @@ import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
import org.eclipse.jdt.internal.compiler.ast.Initializer;
import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.Statement;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.eclipse.jdt.internal.compiler.ast.TypeReference;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
+import lombok.core.AST.Kind;
+import lombok.core.AnnotationValues;
+import lombok.eclipse.handlers.EclipseHandlerUtil;
+
/**
* Eclipse specific version of the LombokNode class.
*/
@@ -264,6 +265,39 @@ public class EclipseNode extends lombok.core.LombokNode<EclipseAST, EclipseNode,
return (ClassFileConstants.AccFinal & f) != 0;
}
+ @Override public boolean isPrimitive() {
+ if (node instanceof FieldDeclaration && !isEnumMember()) {
+ return Eclipse.isPrimitive(((FieldDeclaration) node).type);
+ }
+ if (node instanceof MethodDeclaration) {
+ return Eclipse.isPrimitive(((MethodDeclaration) node).returnType);
+ }
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override public String fieldOrMethodBaseType() {
+ TypeReference typeReference = null;
+ if (node instanceof FieldDeclaration && !isEnumMember()) {
+ typeReference = ((FieldDeclaration) node).type;
+ }
+ if (node instanceof MethodDeclaration) {
+ typeReference = ((MethodDeclaration) node).returnType;
+ }
+ if (typeReference == null) return null;
+
+ String fqn = Eclipse.toQualifiedName(typeReference.getTypeName());
+ if (typeReference.dimensions() == 0) return fqn;
+ StringBuilder result = new StringBuilder(fqn.length() + 2 * typeReference.dimensions());
+ result.append(fqn);
+ for (int i = 0; i < typeReference.dimensions(); i++) {
+ result.append("[]");
+ }
+ return result.toString();
+ }
+
@Override public boolean isTransient() {
if (getKind() != Kind.FIELD) return false;
Integer i = getModifiers();
diff --git a/src/core/lombok/eclipse/TransformEclipseAST.java b/src/core/lombok/eclipse/TransformEclipseAST.java
index 6fcde937..59a0709e 100644
--- a/src/core/lombok/eclipse/TransformEclipseAST.java
+++ b/src/core/lombok/eclipse/TransformEclipseAST.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2019 The Project Lombok Authors.
+ * Copyright (C) 2009-2020 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
@@ -24,6 +24,9 @@ package lombok.eclipse;
import static lombok.eclipse.handlers.EclipseHandlerUtil.*;
import java.lang.reflect.Field;
+import java.util.Collections;
+import java.util.Map;
+import java.util.WeakHashMap;
import lombok.ConfigurationKeys;
import lombok.core.LombokConfiguration;
@@ -63,6 +66,7 @@ public class TransformEclipseAST {
public static boolean disableLombok = false;
private static final HistogramTracker lombokTracker;
+ private static Map<CompilationUnitDeclaration, State> transformationStates = Collections.synchronizedMap(new WeakHashMap<CompilationUnitDeclaration, State>());
static {
String v = System.getProperty("lombok.histogram");
@@ -130,6 +134,30 @@ public class TransformEclipseAST {
}
/**
+ * Check if lombok already handled the given AST. This method will return
+ * <code>true</code> once for diet mode and once for full mode.
+ *
+ * The reason for this is that Eclipse invokes the transform method multiple
+ * times during compilation and it is enough to transform it once and not
+ * repeat the whole thing over and over again.
+ *
+ * @param ast The AST node belonging to the compilation unit (java speak for a single source file).
+ * @return <code>true</code> if this AST was already handled by lombok.
+ */
+ public static boolean alreadyTransformed(CompilationUnitDeclaration ast) {
+ State state = transformationStates.get(ast);
+
+ if (state == State.FULL) return true;
+ if (state == State.DIET) {
+ if (!EclipseAST.isComplete(ast)) return true;
+ transformationStates.put(ast, State.FULL);
+ } else {
+ transformationStates.put(ast, State.DIET);
+ }
+ return false;
+ }
+
+ /**
* This method is called immediately after Eclipse finishes building a CompilationUnitDeclaration, which is
* the top-level AST node when Eclipse parses a source file. The signature is 'magic' - you should not
* change it!
@@ -144,6 +172,7 @@ public class TransformEclipseAST {
if (disableLombok) return;
if (Symbols.hasSymbol("lombok.disable")) return;
+ if (alreadyTransformed(ast)) return;
// Do NOT abort if (ast.bits & ASTNode.HasAllMethodBodies) != 0 - that doesn't work.
@@ -243,4 +272,9 @@ public class TransformEclipseAST {
nextPriority = Math.min(nextPriority, handlers.handleAnnotation(top, annotationNode, annotation, priority));
}
}
+
+ private static enum State {
+ DIET,
+ FULL
+ }
}
diff --git a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java
index 4df7a90b..6bfcf16e 100644
--- a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java
+++ b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java
@@ -26,6 +26,7 @@ import static lombok.eclipse.Eclipse.*;
import static lombok.eclipse.EclipseAugments.*;
import static lombok.eclipse.handlers.EclipseHandlerUtil.EclipseReflectiveMembers.*;
+import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
@@ -48,6 +49,7 @@ import org.eclipse.jdt.internal.compiler.ast.ArrayInitializer;
import org.eclipse.jdt.internal.compiler.ast.ArrayQualifiedTypeReference;
import org.eclipse.jdt.internal.compiler.ast.ArrayTypeReference;
import org.eclipse.jdt.internal.compiler.ast.AssertStatement;
+import org.eclipse.jdt.internal.compiler.ast.BinaryExpression;
import org.eclipse.jdt.internal.compiler.ast.Block;
import org.eclipse.jdt.internal.compiler.ast.CastExpression;
import org.eclipse.jdt.internal.compiler.ast.CharLiteral;
@@ -232,14 +234,7 @@ public class EclipseHandlerUtil {
* @param typeRef A type reference to check.
*/
public static boolean typeMatches(Class<?> type, EclipseNode node, TypeReference typeRef) {
- if (typeRef == null || typeRef.getTypeName() == null || typeRef.getTypeName().length == 0) return false;
- String lastPartA = new String(typeRef.getTypeName()[typeRef.getTypeName().length -1]);
- String lastPartB = type.getSimpleName();
- if (!lastPartA.equals(lastPartB)) return false;
- String typeName = toQualifiedName(typeRef.getTypeName());
-
- TypeResolver resolver = new TypeResolver(node.getImportList());
- return resolver.typeMatches(node, type.getName(), typeName);
+ return typeMatches(type.getName(), node, typeRef);
}
/**
@@ -253,7 +248,7 @@ public class EclipseHandlerUtil {
char[][] tn = typeRef == null ? null : typeRef.getTypeName();
if (tn == null || tn.length == 0) return false;
char[] lastPartA = tn[tn.length - 1];
- int lastIndex = type.lastIndexOf('.') + 1;
+ int lastIndex = Math.max(type.lastIndexOf('.'), type.lastIndexOf('$')) + 1;
if (lastPartA.length != type.length() - lastIndex) return false;
for (int i = 0; i < lastPartA.length; i++) if (lastPartA[i] != type.charAt(i + lastIndex)) return false;
String typeName = toQualifiedName(tn);
@@ -335,14 +330,16 @@ public class EclipseHandlerUtil {
public static final Field STRING_LITERAL__LINE_NUMBER;
public static final Field ANNOTATION__MEMBER_VALUE_PAIR_NAME;
public static final Field TYPE_REFERENCE__ANNOTATIONS;
- public static final Class<?> INTERSECTION_BINDING;
- public static final Field INTERSECTION_BINDING_TYPES;
+ public static final Class<?> INTERSECTION_BINDING1, INTERSECTION_BINDING2;
+ public static final Field INTERSECTION_BINDING_TYPES1, INTERSECTION_BINDING_TYPES2;
static {
STRING_LITERAL__LINE_NUMBER = getField(StringLiteral.class, "lineNumber");
ANNOTATION__MEMBER_VALUE_PAIR_NAME = getField(Annotation.class, "memberValuePairName");
TYPE_REFERENCE__ANNOTATIONS = getField(TypeReference.class, "annotations");
- INTERSECTION_BINDING = getClass("org.eclipse.jdt.internal.compiler.lookup.IntersectionTypeBinding18");
- INTERSECTION_BINDING_TYPES = INTERSECTION_BINDING == null ? null : getField(INTERSECTION_BINDING, "intersectingTypes");
+ INTERSECTION_BINDING1 = getClass("org.eclipse.jdt.internal.compiler.lookup.IntersectionTypeBinding18");
+ INTERSECTION_BINDING2 = getClass("org.eclipse.jdt.internal.compiler.lookup.IntersectionCastTypeBinding");
+ INTERSECTION_BINDING_TYPES1 = INTERSECTION_BINDING1 == null ? null : getField(INTERSECTION_BINDING1, "intersectingTypes");
+ INTERSECTION_BINDING_TYPES2 = INTERSECTION_BINDING2 == null ? null : getField(INTERSECTION_BINDING2, "intersectingTypes");
}
public static int reflectInt(Field f, Object o) {
@@ -386,7 +383,7 @@ public class EclipseHandlerUtil {
}
}
- private static Expression copyAnnotationMemberValue(Expression in) {
+ public static Expression copyAnnotationMemberValue(Expression in) {
Expression out = copyAnnotationMemberValue0(in);
out.constant = in.constant;
return out;
@@ -427,12 +424,11 @@ public class EclipseHandlerUtil {
if (in instanceof SingleNameReference) {
SingleNameReference snr = (SingleNameReference) in;
- long p = (long) s << 32 | e;
- return new SingleNameReference(snr.token, p);
+ return new SingleNameReference(snr.token, pos(in));
}
if (in instanceof QualifiedNameReference) {
QualifiedNameReference qnr = (QualifiedNameReference) in;
- return new QualifiedNameReference(qnr.tokens, qnr.sourcePositions, s, e);
+ return new QualifiedNameReference(qnr.tokens, poss(in, qnr.tokens.length), s, e);
}
// class refs
@@ -448,11 +444,22 @@ public class EclipseHandlerUtil {
out.sourceEnd = e;
out.bits = in.bits;
out.implicitConversion = in.implicitConversion;
- out.statementEnd = in.statementEnd;
+ out.statementEnd = e;
out.expressions = copy;
return out;
}
+ if (in instanceof BinaryExpression) {
+ BinaryExpression be = (BinaryExpression) in;
+ BinaryExpression out = new BinaryExpression(be);
+ out.left = copyAnnotationMemberValue(be.left);
+ out.right = copyAnnotationMemberValue(be.right);
+ out.sourceStart = s;
+ out.sourceEnd = e;
+ out.statementEnd = e;
+ return out;
+ }
+
return in;
}
@@ -660,9 +667,11 @@ public class EclipseHandlerUtil {
Annotation[][] b = new Annotation[a.length][];
for (int i = 0; i < a.length; i++) {
- b[i] = new Annotation[a[i].length];
- for (int j = 0 ; j < a[i].length; j++) {
- b[i][j] = copyAnnotation(a[i][j], a[i][j]);
+ if (a[i] != null) {
+ b[i] = new Annotation[a[i].length];
+ for (int j = 0 ; j < a[i].length; j++) {
+ b[i][j] = copyAnnotation(a[i][j], a[i][j]);
+ }
}
}
@@ -817,6 +826,20 @@ public class EclipseHandlerUtil {
* Searches the given field node for annotations that are specifically intentioned to be copied to the setter.
*/
public static Annotation[] findCopyableToSetterAnnotations(EclipseNode node) {
+ return findAnnotationsInList(node, COPY_TO_SETTER_ANNOTATIONS);
+ }
+
+ /**
+ * Searches the given field node for annotations that are specifically intentioned to be copied to the builder's singular method.
+ */
+ public static Annotation[] findCopyableToBuilderSingularSetterAnnotations(EclipseNode node) {
+ return findAnnotationsInList(node, COPY_TO_BUILDER_SINGULAR_SETTER_ANNOTATIONS);
+ }
+
+ /**
+ * Searches the given field node for annotations that are in the given list, and returns those.
+ */
+ private static Annotation[] findAnnotationsInList(EclipseNode node, java.util.List<String> annotationsToFind) {
AbstractVariableDeclaration avd = (AbstractVariableDeclaration) node.get();
if (avd.annotations == null) return EMPTY_ANNOTATIONS_ARRAY;
List<Annotation> result = new ArrayList<Annotation>();
@@ -824,7 +847,7 @@ public class EclipseHandlerUtil {
for (Annotation annotation : avd.annotations) {
TypeReference typeRef = annotation.type;
if (typeRef != null && typeRef.getTypeName() != null) {
- for (String bn : COPY_TO_SETTER_ANNOTATIONS) if (typeMatches(bn, node, typeRef)) {
+ for (String bn : annotationsToFind) if (typeMatches(bn, node, typeRef)) {
result.add(annotation);
break;
}
@@ -1024,11 +1047,54 @@ public class EclipseHandlerUtil {
return res;
}
-
+
+ private static final char[] OBJECT_SIG = "Ljava/lang/Object;".toCharArray();
+
+ private static int compare(char[] a, char[] b) {
+ if (a == null) return b == null ? 0 : -1;
+ if (b == null) return +1;
+ int len = Math.min(a.length, b.length);
+ for (int i = 0; i < len; i++) {
+ if (a[i] < b[i]) return -1;
+ if (a[i] > b[i]) return +1;
+ }
+ return a.length < b.length ? -1 : a.length > b.length ? +1 : 0;
+ }
+
public static TypeReference makeType(TypeBinding binding, ASTNode pos, boolean allowCompound) {
- if (binding.getClass() == EclipseReflectiveMembers.INTERSECTION_BINDING) {
- Object[] arr = (Object[]) EclipseReflectiveMembers.reflect(EclipseReflectiveMembers.INTERSECTION_BINDING_TYPES, binding);
- binding = (TypeBinding) arr[0];
+ Object[] arr = null;
+ if (binding.getClass() == EclipseReflectiveMembers.INTERSECTION_BINDING1) {
+ arr = (Object[]) EclipseReflectiveMembers.reflect(EclipseReflectiveMembers.INTERSECTION_BINDING_TYPES1, binding);
+ } else if (binding.getClass() == EclipseReflectiveMembers.INTERSECTION_BINDING2) {
+ arr = (Object[]) EclipseReflectiveMembers.reflect(EclipseReflectiveMembers.INTERSECTION_BINDING_TYPES2, binding);
+ }
+
+ if (arr != null) {
+ // Is there a class? Alphabetically lowest wins.
+ TypeBinding winner = null;
+ int winLevel = 0; // 100 = array, 50 = class, 20 = typevar, 15 = wildcard, 10 = interface, 1 = Object.
+ for (Object b : arr) {
+ if (b instanceof TypeBinding) {
+ TypeBinding tb = (TypeBinding) b;
+ int level = 0;
+ if (tb.isArrayType()) level = 100;
+ else if (tb.isClass()) level = 50;
+ else if (tb.isTypeVariable()) level = 20;
+ else if (tb.isWildcard()) level = 15;
+ else level = 10;
+
+ if (level == 50 && compare(tb.signature(), OBJECT_SIG) == 0) level = 1;
+
+ if (winLevel > level) continue;
+ if (winLevel < level) {
+ winner = tb;
+ winLevel = level;
+ continue;
+ }
+ if (compare(winner.signature(), tb.signature()) > 0) winner = tb;
+ }
+ }
+ binding = winner;
}
int dims = binding.dimensions();
binding = binding.leafComponentType();
@@ -1941,7 +2007,11 @@ public class EclipseHandlerUtil {
private static final char[][] EDU_UMD_CS_FINDBUGS_ANNOTATIONS_SUPPRESSFBWARNINGS = Eclipse.fromQualifiedName("edu.umd.cs.findbugs.annotations.SuppressFBWarnings");
public static Annotation[] addSuppressWarningsAll(EclipseNode node, ASTNode source, Annotation[] originalAnnotationArray) {
- Annotation[] anns = addAnnotation(source, originalAnnotationArray, TypeConstants.JAVA_LANG_SUPPRESSWARNINGS, new StringLiteral(ALL, 0, 0, 0));
+ Annotation[] anns = originalAnnotationArray;
+
+ if (!Boolean.FALSE.equals(node.getAst().readConfiguration(ConfigurationKeys.ADD_SUPPRESSWARNINGS_ANNOTATIONS))) {
+ anns = addAnnotation(source, anns, TypeConstants.JAVA_LANG_SUPPRESSWARNINGS, new StringLiteral(ALL, 0, 0, 0));
+ }
if (Boolean.TRUE.equals(node.getAst().readConfiguration(ConfigurationKeys.ADD_FINDBUGS_SUPPRESSWARNINGS_ANNOTATIONS))) {
MemberValuePair mvp = new MemberValuePair(JUSTIFICATION, 0, 0, new StringLiteral(GENERATED_CODE, 0, 0, 0));
@@ -2418,6 +2488,26 @@ public class EclipseHandlerUtil {
return array == null ? null : array.clone();
}
+ public static <T> T[] concat(T[] first, T[] second, Class<T> type) {
+ if (first == null)
+ return second;
+ if (second == null)
+ return first;
+ if (first.length == 0)
+ return second;
+ if (second.length == 0)
+ return first;
+ T[] result = newArray(type, first.length + second.length);
+ System.arraycopy(first, 0, result, 0, first.length);
+ System.arraycopy(second, 0, result, first.length, second.length);
+ return result;
+ }
+
+ @SuppressWarnings("unchecked")
+ private static <T> T[] newArray(Class<T> type, int length) {
+ return (T[]) Array.newInstance(type, length);
+ }
+
public static boolean isDirectDescendantOfObject(EclipseNode typeNode) {
if (!(typeNode.get() instanceof TypeDeclaration)) throw new IllegalArgumentException("not a type node");
TypeDeclaration typeDecl = (TypeDeclaration) typeNode.get();
diff --git a/src/core/lombok/eclipse/handlers/HandleBuilder.java b/src/core/lombok/eclipse/handlers/HandleBuilder.java
index b8e88522..801fe7e7 100755
--- a/src/core/lombok/eclipse/handlers/HandleBuilder.java
+++ b/src/core/lombok/eclipse/handlers/HandleBuilder.java
@@ -57,6 +57,7 @@ import org.eclipse.jdt.internal.compiler.ast.ParameterizedSingleTypeReference;
import org.eclipse.jdt.internal.compiler.ast.QualifiedAllocationExpression;
import org.eclipse.jdt.internal.compiler.ast.QualifiedThisReference;
import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.Receiver;
import org.eclipse.jdt.internal.compiler.ast.ReturnStatement;
import org.eclipse.jdt.internal.compiler.ast.SingleMemberAnnotation;
import org.eclipse.jdt.internal.compiler.ast.SingleNameReference;
@@ -485,7 +486,7 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
List<Included<EclipseNode, ToString.Include>> fieldNodes = new ArrayList<Included<EclipseNode, ToString.Include>>();
for (BuilderFieldData bfd : builderFields) {
for (EclipseNode f : bfd.createdFields) {
- fieldNodes.add(new Included<EclipseNode, ToString.Include>(f, null, true));
+ fieldNodes.add(new Included<EclipseNode, ToString.Include>(f, null, true, false));
}
}
MethodDeclaration md = HandleToString.createToString(builderType, fieldNodes, true, false, ast, FieldAccess.ALWAYS_FIELD);
@@ -683,7 +684,7 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
return decl;
}
- static Argument[] generateBuildArgs(CheckerFrameworkVersion cfv, EclipseNode type, List<BuilderFieldData> builderFields, ASTNode source) {
+ static Receiver generateBuildReceiver(CheckerFrameworkVersion cfv, EclipseNode type, List<BuilderFieldData> builderFields, ASTNode source) {
if (!cfv.generateCalledMethods()) return null;
List<char[]> mandatories = new ArrayList<char[]>();
@@ -706,9 +707,11 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
}
ann.memberValue = arr;
}
- Argument arg = new Argument(new char[] { 't', 'h', 'i', 's' }, 0, generateTypeReference(type, source.sourceStart), Modifier.FINAL);
- arg.annotations = new Annotation[] {ann};
- return new Argument[] {arg};
+
+ QualifiedTypeReference typeReference = (QualifiedTypeReference) generateTypeReference(type, source.sourceStart);
+ typeReference.annotations = new Annotation[typeReference.tokens.length][];
+ typeReference.annotations[0] = new Annotation[] {ann};
+ return new Receiver(new char[] { 't', 'h', 'i', 's' }, 0, typeReference, null, Modifier.FINAL);
}
public MethodDeclaration generateBuildMethod(CheckerFrameworkVersion cfv, EclipseNode tdParent, boolean isStatic, String name, char[] staticName, TypeReference returnType, List<BuilderFieldData> builderFields, EclipseNode type, TypeReference[] thrownExceptions, boolean addCleaning, ASTNode source, AccessLevel access) {
@@ -802,7 +805,7 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
if (cfv.generateSideEffectFree()) {
out.annotations = new Annotation[] {generateNamedAnnotation(source, CheckerFrameworkVersion.NAME__SIDE_EFFECT_FREE)};
}
- out.arguments = generateBuildArgs(cfv, type, builderFields, source);
+ out.receiver = generateBuildReceiver(cfv, type, builderFields, source);
if (staticName == null) createRelevantNonNullAnnotation(type, out);
out.traverse(new SetGeneratedByVisitor(source), (ClassScope) null);
return out;
@@ -953,16 +956,14 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
MethodDeclaration setter = HandleSetter.createSetter(td, deprecate, fieldNode, setterName, paramName, nameOfSetFlag, chain, toEclipseModifier(access),
sourceNode, methodAnnsList, annotations != null ? Arrays.asList(copyAnnotations(source, annotations)) : Collections.<Annotation>emptyList());
if (cfv.generateCalledMethods()) {
- Argument[] arr = setter.arguments == null ? new Argument[0] : setter.arguments;
- Argument[] newArr = new Argument[arr.length + 1];
- System.arraycopy(arr, 0, newArr, 1, arr.length);
- newArr[0] = new Argument(new char[] { 't', 'h', 'i', 's' }, 0, generateTypeReference(builderType, 0), Modifier.FINAL);
char[][] nameNotCalled = fromQualifiedName(CheckerFrameworkVersion.NAME__NOT_CALLED);
- SingleMemberAnnotation ann = new SingleMemberAnnotation(new QualifiedTypeReference(nameNotCalled, poss(
- source, nameNotCalled.length)), source.sourceStart);
+ SingleMemberAnnotation ann = new SingleMemberAnnotation(new QualifiedTypeReference(nameNotCalled, poss(source, nameNotCalled.length)), source.sourceStart);
ann.memberValue = new StringLiteral(setterName.toCharArray(), 0, 0, 0);
- newArr[0].annotations = new Annotation[] {ann};
- setter.arguments = newArr;
+
+ QualifiedTypeReference typeReference = (QualifiedTypeReference) generateTypeReference(builderType, 0);
+ typeReference.annotations = new Annotation[typeReference.tokens.length][];
+ typeReference.annotations[0] = new Annotation[] {ann};
+ setter.receiver = new Receiver(new char[] { 't', 'h', 'i', 's' }, 0, typeReference, null, Modifier.FINAL);
}
injectMethod(builderType, setter);
}
diff --git a/src/core/lombok/eclipse/handlers/HandleConstructor.java b/src/core/lombok/eclipse/handlers/HandleConstructor.java
index 129fa7c0..06c9ecd9 100755
--- a/src/core/lombok/eclipse/handlers/HandleConstructor.java
+++ b/src/core/lombok/eclipse/handlers/HandleConstructor.java
@@ -84,13 +84,14 @@ import org.mangosdk.spi.ProviderFor;
public class HandleConstructor {
@ProviderFor(EclipseAnnotationHandler.class)
public static class HandleNoArgsConstructor extends EclipseAnnotationHandler<NoArgsConstructor> {
+ private static final String NAME = NoArgsConstructor.class.getSimpleName();
private HandleConstructor handleConstructor = new HandleConstructor();
@Override public void handle(AnnotationValues<NoArgsConstructor> annotation, Annotation ast, EclipseNode annotationNode) {
handleFlagUsage(annotationNode, ConfigurationKeys.NO_ARGS_CONSTRUCTOR_FLAG_USAGE, "@NoArgsConstructor", ConfigurationKeys.ANY_CONSTRUCTOR_FLAG_USAGE, "any @xArgsConstructor");
EclipseNode typeNode = annotationNode.up();
- if (!checkLegality(typeNode, annotationNode, NoArgsConstructor.class.getSimpleName())) return;
+ if (!checkLegality(typeNode, annotationNode, NAME)) return;
NoArgsConstructor ann = annotation.getInstance();
AccessLevel level = ann.access();
String staticName = ann.staticName();
@@ -106,13 +107,14 @@ public class HandleConstructor {
@ProviderFor(EclipseAnnotationHandler.class)
public static class HandleRequiredArgsConstructor extends EclipseAnnotationHandler<RequiredArgsConstructor> {
+ private static final String NAME = RequiredArgsConstructor.class.getSimpleName();
private HandleConstructor handleConstructor = new HandleConstructor();
@Override public void handle(AnnotationValues<RequiredArgsConstructor> annotation, Annotation ast, EclipseNode annotationNode) {
handleFlagUsage(annotationNode, ConfigurationKeys.REQUIRED_ARGS_CONSTRUCTOR_FLAG_USAGE, "@RequiredArgsConstructor", ConfigurationKeys.ANY_CONSTRUCTOR_FLAG_USAGE, "any @xArgsConstructor");
EclipseNode typeNode = annotationNode.up();
- if (!checkLegality(typeNode, annotationNode, RequiredArgsConstructor.class.getSimpleName())) return;
+ if (!checkLegality(typeNode, annotationNode, NAME)) return;
RequiredArgsConstructor ann = annotation.getInstance();
AccessLevel level = ann.access();
if (level == AccessLevel.NONE) return;
@@ -166,13 +168,15 @@ public class HandleConstructor {
@ProviderFor(EclipseAnnotationHandler.class)
public static class HandleAllArgsConstructor extends EclipseAnnotationHandler<AllArgsConstructor> {
+ private static final String NAME = AllArgsConstructor.class.getSimpleName();
+
private HandleConstructor handleConstructor = new HandleConstructor();
@Override public void handle(AnnotationValues<AllArgsConstructor> annotation, Annotation ast, EclipseNode annotationNode) {
handleFlagUsage(annotationNode, ConfigurationKeys.ALL_ARGS_CONSTRUCTOR_FLAG_USAGE, "@AllArgsConstructor", ConfigurationKeys.ANY_CONSTRUCTOR_FLAG_USAGE, "any @xArgsConstructor");
EclipseNode typeNode = annotationNode.up();
- if (!checkLegality(typeNode, annotationNode, AllArgsConstructor.class.getSimpleName())) return;
+ if (!checkLegality(typeNode, annotationNode, NAME)) return;
AllArgsConstructor ann = annotation.getInstance();
AccessLevel level = ann.access();
if (level == AccessLevel.NONE) return;
diff --git a/src/core/lombok/eclipse/handlers/HandleFieldNameConstants.java b/src/core/lombok/eclipse/handlers/HandleFieldNameConstants.java
index 2db7591c..cee3912c 100644
--- a/src/core/lombok/eclipse/handlers/HandleFieldNameConstants.java
+++ b/src/core/lombok/eclipse/handlers/HandleFieldNameConstants.java
@@ -136,9 +136,8 @@ public class HandleFieldNameConstants extends EclipseAnnotationHandler<FieldName
EclipseNode fieldsType = findInnerClass(typeNode, innerTypeName.getName());
boolean genConstr = false, genClinit = false;
char[] name = innerTypeName.getCharArray();
- TypeDeclaration generatedInnerType = null;
if (fieldsType == null) {
- generatedInnerType = new TypeDeclaration(parent.compilationResult);
+ TypeDeclaration generatedInnerType = new TypeDeclaration(parent.compilationResult);
generatedInnerType.bits |= Eclipse.ECLIPSE_DO_NOT_TOUCH_FLAG;
generatedInnerType.modifiers = toEclipseModifier(level) | (asEnum ? ClassFileConstants.AccEnum : (ClassFileConstants.AccStatic | ClassFileConstants.AccFinal));
generatedInnerType.name = name;
@@ -172,10 +171,10 @@ public class HandleFieldNameConstants extends EclipseAnnotationHandler<FieldName
injectMethod(fieldsType, constructor);
}
+ Clinit cli = null;
if (genClinit) {
- Clinit cli = new Clinit(parent.compilationResult);
+ cli = new Clinit(parent.compilationResult);
injectMethod(fieldsType, cli);
- cli.traverse(generatedByVisitor, ((TypeDeclaration) fieldsType.get()).scope);
}
for (EclipseNode fieldNode : fields) {
@@ -194,6 +193,7 @@ public class HandleFieldNameConstants extends EclipseAnnotationHandler<FieldName
ac.sourceEnd = source.sourceEnd;
constantField.initialization = ac;
constantField.modifiers = 0;
+ ((TypeDeclaration) fieldsType.get()).enumConstantsCounter++;
} else {
constantField.type = new QualifiedTypeReference(TypeConstants.JAVA_LANG_STRING, new long[] {p, p, p});
constantField.initialization = new StringLiteral(field.name, pS, pE, 0);
@@ -202,5 +202,9 @@ public class HandleFieldNameConstants extends EclipseAnnotationHandler<FieldName
injectField(fieldsType, constantField);
constantField.traverse(generatedByVisitor, ((TypeDeclaration) fieldsType.get()).initializerScope);
}
+
+ if (genClinit) {
+ cli.traverse(generatedByVisitor, ((TypeDeclaration) fieldsType.get()).scope);
+ }
}
}
diff --git a/src/core/lombok/eclipse/handlers/HandleGetter.java b/src/core/lombok/eclipse/handlers/HandleGetter.java
index 30b4a699..9cd1e2a1 100644
--- a/src/core/lombok/eclipse/handlers/HandleGetter.java
+++ b/src/core/lombok/eclipse/handlers/HandleGetter.java
@@ -285,10 +285,13 @@ public class HandleGetter extends EclipseAnnotationHandler<Getter> {
}
if (addSuppressWarningsUnchecked) {
+ List<Expression> suppressions = new ArrayList<Expression>(2);
+ if (!Boolean.FALSE.equals(fieldNode.getAst().readConfiguration(ConfigurationKeys.ADD_SUPPRESSWARNINGS_ANNOTATIONS))) {
+ suppressions.add(new StringLiteral(ALL, 0, 0, 0));
+ }
+ suppressions.add(new StringLiteral(UNCHECKED, 0, 0, 0));
ArrayInitializer arr = new ArrayInitializer();
- arr.expressions = new Expression[2];
- arr.expressions[0] = new StringLiteral(ALL, 0, 0, 0);
- arr.expressions[1] = new StringLiteral(UNCHECKED, 0, 0, 0);
+ arr.expressions = suppressions.toArray(new Expression[0]);
method.annotations = addAnnotation(source, method.annotations, TypeConstants.JAVA_LANG_SUPPRESSWARNINGS, arr);
}
diff --git a/src/core/lombok/eclipse/handlers/HandleLog.java b/src/core/lombok/eclipse/handlers/HandleLog.java
index 7a140193..a0e431e5 100644
--- a/src/core/lombok/eclipse/handlers/HandleLog.java
+++ b/src/core/lombok/eclipse/handlers/HandleLog.java
@@ -51,6 +51,7 @@ import lombok.core.configuration.LogDeclaration.LogFactoryParameter;
import lombok.core.handlers.LoggingFramework;
import lombok.eclipse.EclipseAnnotationHandler;
import lombok.eclipse.EclipseNode;
+import lombok.eclipse.handlers.EclipseHandlerUtil.MemberExistsResult;
public class HandleLog {
private static final IdentifierName LOG = IdentifierName.valueOf("log");
@@ -59,7 +60,7 @@ public class HandleLog {
throw new UnsupportedOperationException();
}
- public static void processAnnotation(LoggingFramework framework, AnnotationValues<? extends java.lang.annotation.Annotation> annotation, Annotation source, EclipseNode annotationNode, String loggerTopic) {
+ public static void processAnnotation(LoggingFramework framework, AnnotationValues<? extends java.lang.annotation.Annotation> annotation, Annotation source, EclipseNode annotationNode) {
EclipseNode owner = annotationNode.up();
switch (owner.getKind()) {
@@ -84,15 +85,18 @@ public class HandleLog {
annotationNode.addWarning("Field '" + logFieldName + "' already exists.");
return;
}
-
- if (loggerTopic != null && loggerTopic.trim().isEmpty()) loggerTopic = null;
+
+ Object valueGuess = annotation.getValueGuess("topic");
+ Expression loggerTopic = (Expression) annotation.getActualExpression("topic");
+
+ if (valueGuess instanceof String && ((String) valueGuess).trim().isEmpty()) loggerTopic = null;
if (framework.getDeclaration().getParametersWithTopic() == null && loggerTopic != null) {
annotationNode.addError(framework.getAnnotationAsString() + " does not allow a topic.");
loggerTopic = null;
}
if (framework.getDeclaration().getParametersWithoutTopic() == null && loggerTopic == null) {
annotationNode.addError(framework.getAnnotationAsString() + " requires a topic.");
- loggerTopic = "";
+ loggerTopic = new StringLiteral(new char[]{}, 0, 0, 0);
}
ClassLiteralAccess loggingType = selfType(owner, source);
@@ -122,7 +126,7 @@ public class HandleLog {
return result;
}
- private static FieldDeclaration createField(LoggingFramework framework, Annotation source, ClassLiteralAccess loggingType, String logFieldName, boolean useStatic, String loggerTopic) {
+ private static FieldDeclaration createField(LoggingFramework framework, Annotation source, ClassLiteralAccess loggingType, String logFieldName, boolean useStatic, Expression loggerTopic) {
int pS = source.sourceStart, pE = source.sourceEnd;
long p = (long) pS << 32 | pE;
@@ -165,7 +169,7 @@ public class HandleLog {
return typeReference;
}
- private static final Expression[] createFactoryParameters(ClassLiteralAccess loggingType, Annotation source, List<LogFactoryParameter> parameters, String loggerTopic) {
+ private static final Expression[] createFactoryParameters(ClassLiteralAccess loggingType, Annotation source, List<LogFactoryParameter> parameters, Expression loggerTopic) {
Expression[] expressions = new Expression[parameters.size()];
int pS = source.sourceStart, pE = source.sourceEnd;
@@ -192,7 +196,7 @@ public class HandleLog {
expressions[i] = factoryParameterCall;
break;
case TOPIC:
- expressions[i] = new StringLiteral(loggerTopic.toCharArray(), pS, pE, 0);
+ expressions[i] = EclipseHandlerUtil.copyAnnotationMemberValue(loggerTopic);
break;
case NULL:
expressions[i] = new NullLiteral(pS, pE);
@@ -219,7 +223,7 @@ public class HandleLog {
public static class HandleCommonsLog extends EclipseAnnotationHandler<lombok.extern.apachecommons.CommonsLog> {
@Override public void handle(AnnotationValues<lombok.extern.apachecommons.CommonsLog> annotation, Annotation source, EclipseNode annotationNode) {
handleFlagUsage(annotationNode, ConfigurationKeys.LOG_COMMONS_FLAG_USAGE, "@apachecommons.CommonsLog", ConfigurationKeys.LOG_ANY_FLAG_USAGE, "any @Log");
- processAnnotation(LoggingFramework.COMMONS, annotation, source, annotationNode, annotation.getInstance().topic());
+ processAnnotation(LoggingFramework.COMMONS, annotation, source, annotationNode);
}
}
@@ -230,7 +234,7 @@ public class HandleLog {
public static class HandleJulLog extends EclipseAnnotationHandler<lombok.extern.java.Log> {
@Override public void handle(AnnotationValues<lombok.extern.java.Log> annotation, Annotation source, EclipseNode annotationNode) {
handleFlagUsage(annotationNode, ConfigurationKeys.LOG_JUL_FLAG_USAGE, "@java.Log", ConfigurationKeys.LOG_ANY_FLAG_USAGE, "any @Log");
- processAnnotation(LoggingFramework.JUL, annotation, source, annotationNode, annotation.getInstance().topic());
+ processAnnotation(LoggingFramework.JUL, annotation, source, annotationNode);
}
}
@@ -241,7 +245,7 @@ public class HandleLog {
public static class HandleLog4jLog extends EclipseAnnotationHandler<lombok.extern.log4j.Log4j> {
@Override public void handle(AnnotationValues<lombok.extern.log4j.Log4j> annotation, Annotation source, EclipseNode annotationNode) {
handleFlagUsage(annotationNode, ConfigurationKeys.LOG_LOG4J_FLAG_USAGE, "@Log4j", ConfigurationKeys.LOG_ANY_FLAG_USAGE, "any @Log");
- processAnnotation(LoggingFramework.LOG4J, annotation, source, annotationNode, annotation.getInstance().topic());
+ processAnnotation(LoggingFramework.LOG4J, annotation, source, annotationNode);
}
}
@@ -252,7 +256,7 @@ public class HandleLog {
public static class HandleLog4j2Log extends EclipseAnnotationHandler<lombok.extern.log4j.Log4j2> {
@Override public void handle(AnnotationValues<lombok.extern.log4j.Log4j2> annotation, Annotation source, EclipseNode annotationNode) {
handleFlagUsage(annotationNode, ConfigurationKeys.LOG_LOG4J2_FLAG_USAGE, "@Log4j2", ConfigurationKeys.LOG_ANY_FLAG_USAGE, "any @Log");
- processAnnotation(LoggingFramework.LOG4J2, annotation, source, annotationNode, annotation.getInstance().topic());
+ processAnnotation(LoggingFramework.LOG4J2, annotation, source, annotationNode);
}
}
@@ -263,7 +267,7 @@ public class HandleLog {
public static class HandleSlf4jLog extends EclipseAnnotationHandler<lombok.extern.slf4j.Slf4j> {
@Override public void handle(AnnotationValues<lombok.extern.slf4j.Slf4j> annotation, Annotation source, EclipseNode annotationNode) {
handleFlagUsage(annotationNode, ConfigurationKeys.LOG_SLF4J_FLAG_USAGE, "@Slf4j", ConfigurationKeys.LOG_ANY_FLAG_USAGE, "any @Log");
- processAnnotation(LoggingFramework.SLF4J, annotation, source, annotationNode, annotation.getInstance().topic());
+ processAnnotation(LoggingFramework.SLF4J, annotation, source, annotationNode);
}
}
@@ -274,7 +278,7 @@ public class HandleLog {
public static class HandleXSlf4jLog extends EclipseAnnotationHandler<lombok.extern.slf4j.XSlf4j> {
@Override public void handle(AnnotationValues<lombok.extern.slf4j.XSlf4j> annotation, Annotation source, EclipseNode annotationNode) {
handleFlagUsage(annotationNode, ConfigurationKeys.LOG_XSLF4J_FLAG_USAGE, "@XSlf4j", ConfigurationKeys.LOG_ANY_FLAG_USAGE, "any @Log");
- processAnnotation(LoggingFramework.XSLF4J, annotation, source, annotationNode, annotation.getInstance().topic());
+ processAnnotation(LoggingFramework.XSLF4J, annotation, source, annotationNode);
}
}
@@ -285,7 +289,7 @@ public class HandleLog {
public static class HandleJBossLog extends EclipseAnnotationHandler<lombok.extern.jbosslog.JBossLog> {
@Override public void handle(AnnotationValues<lombok.extern.jbosslog.JBossLog> annotation, Annotation source, EclipseNode annotationNode) {
handleFlagUsage(annotationNode, ConfigurationKeys.LOG_JBOSSLOG_FLAG_USAGE, "@JBossLog", ConfigurationKeys.LOG_ANY_FLAG_USAGE, "any @Log");
- processAnnotation(LoggingFramework.JBOSSLOG, annotation, source, annotationNode, annotation.getInstance().topic());
+ processAnnotation(LoggingFramework.JBOSSLOG, annotation, source, annotationNode);
}
}
@@ -296,7 +300,7 @@ public class HandleLog {
public static class HandleFloggerLog extends EclipseAnnotationHandler<lombok.extern.flogger.Flogger> {
@Override public void handle(AnnotationValues<lombok.extern.flogger.Flogger> annotation, Annotation source, EclipseNode annotationNode) {
handleFlagUsage(annotationNode, ConfigurationKeys.LOG_FLOGGER_FLAG_USAGE, "@Flogger", ConfigurationKeys.LOG_ANY_FLAG_USAGE, "any @Log");
- processAnnotation(LoggingFramework.FLOGGER, annotation, source, annotationNode, "");
+ processAnnotation(LoggingFramework.FLOGGER, annotation, source, annotationNode);
}
}
@@ -313,7 +317,7 @@ public class HandleLog {
return;
}
LoggingFramework framework = new LoggingFramework(lombok.CustomLog.class, logDeclaration);
- processAnnotation(framework, annotation, source, annotationNode, annotation.getInstance().topic());
+ processAnnotation(framework, annotation, source, annotationNode);
}
}
}
diff --git a/src/core/lombok/eclipse/handlers/HandleNonNull.java b/src/core/lombok/eclipse/handlers/HandleNonNull.java
index c4d42c2e..903d098b 100644
--- a/src/core/lombok/eclipse/handlers/HandleNonNull.java
+++ b/src/core/lombok/eclipse/handlers/HandleNonNull.java
@@ -40,7 +40,6 @@ import org.eclipse.jdt.internal.compiler.ast.Expression;
import org.eclipse.jdt.internal.compiler.ast.IfStatement;
import org.eclipse.jdt.internal.compiler.ast.MessageSend;
import org.eclipse.jdt.internal.compiler.ast.NullLiteral;
-import org.eclipse.jdt.internal.compiler.ast.OperatorIds;
import org.eclipse.jdt.internal.compiler.ast.SingleNameReference;
import org.eclipse.jdt.internal.compiler.ast.Statement;
import org.eclipse.jdt.internal.compiler.ast.SynchronizedStatement;
@@ -232,11 +231,11 @@ public class HandleNonNull extends EclipseAnnotationHandler<NonNull> {
Expression cond = isIf ? ((IfStatement) stat).condition : ((AssertStatement) stat).assertExpression;
if (!(cond instanceof EqualExpression)) return null;
EqualExpression bin = (EqualExpression) cond;
- int operatorId = ((bin.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT);
+ String op = bin.operatorToString();
if (isIf) {
- if (operatorId != OperatorIds.EQUAL_EQUAL) return null;
+ if (!"==".equals(op)) return null;
} else {
- if (operatorId != OperatorIds.NOT_EQUAL) return null;
+ if (!"!=".equals(op)) return null;
}
if (!(bin.left instanceof SingleNameReference)) return null;
if (!(bin.right instanceof NullLiteral)) return null;
diff --git a/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java b/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java
index 6634d1c8..b1e7c419 100644
--- a/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java
+++ b/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java
@@ -57,6 +57,7 @@ import org.eclipse.jdt.internal.compiler.ast.ParameterizedQualifiedTypeReference
import org.eclipse.jdt.internal.compiler.ast.ParameterizedSingleTypeReference;
import org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference;
import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference;
+import org.eclipse.jdt.internal.compiler.ast.Receiver;
import org.eclipse.jdt.internal.compiler.ast.ReturnStatement;
import org.eclipse.jdt.internal.compiler.ast.SingleMemberAnnotation;
import org.eclipse.jdt.internal.compiler.ast.SingleNameReference;
@@ -144,9 +145,9 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
generateBuilderMethod = true;
}
if (!checkName("buildMethodName", buildMethodName, annotationNode)) return;
-
+
boolean toBuilder = superbuilderAnnotation.toBuilder();
-
+
EclipseNode tdParent = annotationNode.up();
java.util.List<BuilderFieldData> builderFields = new ArrayList<BuilderFieldData>();
@@ -233,7 +234,7 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
TypeReference extendsClause = td.superclass;
TypeReference superclassBuilderClass = null;
TypeReference[] typeArguments = new TypeReference[] {
- new SingleTypeReference(classGenericName.toCharArray(), 0),
+ new SingleTypeReference(classGenericName.toCharArray(), 0),
new SingleTypeReference(builderGenericName.toCharArray(), 0)
};
if (extendsClause instanceof QualifiedTypeReference) {
@@ -242,7 +243,7 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
String superclassBuilderClassName = builderClassNameTemplate.replace("*", superclassClassName);
char[][] tokens = Arrays.copyOf(qualifiedTypeReference.tokens, qualifiedTypeReference.tokens.length + 1);
- tokens[tokens.length] = superclassBuilderClassName.toCharArray();
+ tokens[tokens.length-1] = superclassBuilderClassName.toCharArray();
long[] poss = new long[tokens.length];
Arrays.fill(poss, p);
@@ -274,8 +275,10 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
// If there is no superclass, superclassBuilderClassExpression is still == null at this point.
// You can use it to check whether to inherit or not.
- generateBuilderBasedConstructor(cfv, tdParent, typeParams, builderFields, annotationNode, builderClassName,
- superclassBuilderClass != null);
+ if (!constructorExists(tdParent, builderClassName)) {
+ generateBuilderBasedConstructor(cfv, tdParent, typeParams, builderFields, annotationNode, builderClassName,
+ superclassBuilderClass != null);
+ }
// Create the abstract builder class, or reuse an existing one.
EclipseNode builderType = findInnerClass(tdParent, builderClassName);
@@ -330,14 +333,14 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
cleanDecl.type = TypeReference.baseTypeReference(TypeIds.T_boolean, 0);
injectFieldAndMarkGenerated(builderType, cleanDecl);
}
-
+
if (toBuilder) {
// Generate $fillValuesFrom() method in the abstract builder.
injectMethod(builderType, generateFillValuesMethod(tdParent, superclassBuilderClass != null, builderGenericName, classGenericName, builderClassName, typeParams));
// Generate $fillValuesFromInstanceIntoBuilder() method in the builder implementation class.
injectMethod(builderType, generateStaticFillValuesMethod(tdParent, builderClassName, typeParams, builderFields, ast, superbuilderAnnotation.setterPrefix()));
}
-
+
// Generate abstract self() and build() methods in the abstract builder.
injectMethod(builderType, generateAbstractSelfMethod(cfv, tdParent, superclassBuilderClass != null, builderGenericName));
injectMethod(builderType, generateAbstractBuildMethod(cfv, builderType, buildMethodName, builderFields, superclassBuilderClass != null, classGenericName, ast));
@@ -352,7 +355,7 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
List<Included<EclipseNode, ToString.Include>> fieldNodes = new ArrayList<Included<EclipseNode, ToString.Include>>();
for (BuilderFieldData bfd : builderFields) {
for (EclipseNode f : bfd.createdFields) {
- fieldNodes.add(new Included<EclipseNode, ToString.Include>(f, null, true));
+ fieldNodes.add(new Included<EclipseNode, ToString.Include>(f, null, true, false));
}
}
// Let toString() call super.toString() if there is a superclass, so that it also shows fields from the superclass' builder.
@@ -383,22 +386,23 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
}
sanityCheckForMethodGeneratingAnnotationsOnBuilderClass(builderImplType, annotationNode);
}
-
+
if (toBuilder) {
// Add the toBuilder() method to the annotated class.
switch (methodExists(TO_BUILDER_METHOD_NAME_STRING, tdParent, 0)) {
case EXISTS_BY_USER:
- annotationNode.addWarning("Not generating toBuilder() as it already exists.");
break;
case NOT_EXISTS:
injectMethod(tdParent, generateToBuilderMethod(cfv, builderClassName, builderImplClassName, tdParent, typeParams, ast));
+ break;
default:
// Should not happen.
}
}
-
+
// Create the self() and build() methods in the BuilderImpl.
injectMethod(builderImplType, generateSelfMethod(cfv, builderImplType, typeParams, p));
+
if (methodExists(buildMethodName, builderImplType, -1) == MemberExistsResult.NOT_EXISTS) {
injectMethod(builderImplType, generateBuildMethod(cfv, builderImplType, buildMethodName, returnType, builderFields, ast));
}
@@ -416,7 +420,7 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
}
}
}
-
+
private EclipseNode generateBuilderAbstractClass(EclipseNode tdParent, String builderClass,
TypeReference superclassBuilderClass, TypeParameter[] typeParams,
ASTNode source, String classGenericName, String builderGenericName) {
@@ -445,7 +449,7 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
builder.superclass = copyType(superclassBuilderClass, source);
builder.createDefaultConstructor(false, true);
-
+
builder.traverse(new SetGeneratedByVisitor(source), (ClassScope) null);
return injectType(tdParent, builder);
}
@@ -803,8 +807,8 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
out.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
out.modifiers = ClassFileConstants.AccProtected;
Annotation overrideAnn = makeMarkerAnnotation(TypeConstants.JAVA_LANG_OVERRIDE, builderImplType.get());
- Annotation rrAnn = cfv.generateReturnsReceiver() ? generateNamedAnnotation(builderImplType.get(), CheckerFrameworkVersion.NAME__RETURNS_RECEIVER): null;
- Annotation sefAnn = cfv.generatePure() ? generateNamedAnnotation(builderImplType.get(), CheckerFrameworkVersion.NAME__PURE): null;
+ Annotation rrAnn = cfv.generateReturnsReceiver() ? generateNamedAnnotation(builderImplType.get(), CheckerFrameworkVersion.NAME__RETURNS_RECEIVER) : null;
+ Annotation sefAnn = cfv.generatePure() ? generateNamedAnnotation(builderImplType.get(), CheckerFrameworkVersion.NAME__PURE) : null;
if (rrAnn != null && sefAnn != null) out.annotations = new Annotation[] {overrideAnn, rrAnn, sefAnn};
else if (rrAnn != null) out.annotations = new Annotation[] {overrideAnn, rrAnn};
else if (sefAnn != null) out.annotations = new Annotation[] {overrideAnn, sefAnn};
@@ -829,7 +833,7 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
if (overrideAnn != null && sefAnn != null) out.annotations = new Annotation[] {overrideAnn, sefAnn};
else if (overrideAnn != null) out.annotations = new Annotation[] {overrideAnn};
else if (sefAnn != null) out.annotations = new Annotation[] {sefAnn};
- out.arguments = HandleBuilder.generateBuildArgs(cfv, builderType, builderFields, source);
+ out.receiver = HandleBuilder.generateBuildReceiver(cfv, builderType, builderFields, source);
out.traverse(new SetGeneratedByVisitor(source), (ClassScope) null);
return out;
}
@@ -854,7 +858,7 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
allocationStatement.arguments = new Expression[] {new ThisReference(0, 0)};
statements.add(new ReturnStatement(allocationStatement, 0, 0));
out.statements = statements.isEmpty() ? null : statements.toArray(new Statement[0]);
- out.arguments = HandleBuilder.generateBuildArgs(cfv, builderType, builderFields, source);
+ out.receiver = HandleBuilder.generateBuildReceiver(cfv, builderType, builderFields, source);
createRelevantNonNullAnnotation(builderType, out);
out.traverse(new SetGeneratedByVisitor(source), (ClassScope) null);
return out;
@@ -968,15 +972,14 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
MethodDeclaration setter = HandleSetter.createSetter(td, deprecate, fieldNode, setterName, paramName, nameOfSetFlag, returnType, returnStatement, ClassFileConstants.AccPublic,
sourceNode, methodAnnsList, annosOnParam != null ? Arrays.asList(copyAnnotations(source, annosOnParam)) : Collections.<Annotation>emptyList());
if (cfv.generateCalledMethods()) {
- Argument[] arr = setter.arguments == null ? new Argument[0] : setter.arguments;
- Argument[] newArr = new Argument[arr.length + 1];
- System.arraycopy(arr, 0, newArr, 1, arr.length);
- newArr[0] = new Argument(new char[] { 't', 'h', 'i', 's' }, 0, generateTypeReference(builderType, 0), Modifier.FINAL);
char[][] nameNotCalled = fromQualifiedName(CheckerFrameworkVersion.NAME__NOT_CALLED);
SingleMemberAnnotation ann = new SingleMemberAnnotation(new QualifiedTypeReference(nameNotCalled, poss(source, nameNotCalled.length)), source.sourceStart);
ann.memberValue = new StringLiteral(setterName.toCharArray(), 0, 0, 0);
- newArr[0].annotations = new Annotation[] {ann};
- setter.arguments = newArr;
+
+ QualifiedTypeReference typeReference = (QualifiedTypeReference) generateTypeReference(builderType, 0);
+ typeReference.annotations = new Annotation[typeReference.tokens.length][];
+ typeReference.annotations[0] = new Annotation[] {ann};
+ setter.receiver = new Receiver(new char[] { 't', 'h', 'i', 's' }, 0, typeReference, null, Modifier.FINAL);
}
injectMethod(builderType, setter);
}
@@ -1159,4 +1162,26 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
System.arraycopy(name, 0, out, prefix.length, name.length);
return out;
}
+
+ private boolean constructorExists(EclipseNode type, String builderClassName) {
+ if (type != null && type.get() instanceof TypeDeclaration) {
+ TypeDeclaration typeDecl = (TypeDeclaration)type.get();
+ if (typeDecl.methods != null) for (AbstractMethodDeclaration def : typeDecl.methods) {
+ if (def instanceof ConstructorDeclaration) {
+ if ((def.bits & ASTNode.IsDefaultConstructor) != 0) continue;
+ if (!def.isConstructor()) continue;
+ if (isTolerate(type, def)) continue;
+ if (def.arguments.length != 1) continue;
+
+ // Cannot use typeMatches() here, because the parameter could be fully-qualified, partially-qualified, or not qualified.
+ // A string-compare of the last part should work. If it's a false-positive, users could still @Tolerate it.
+ char[] typeName = def.arguments[0].type.getLastToken();
+ if (builderClassName.equals(String.valueOf(typeName)))
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
}
diff --git a/src/core/lombok/eclipse/handlers/HandleUtilityClass.java b/src/core/lombok/eclipse/handlers/HandleUtilityClass.java
index ada09d0e..2349f839 100644
--- a/src/core/lombok/eclipse/handlers/HandleUtilityClass.java
+++ b/src/core/lombok/eclipse/handlers/HandleUtilityClass.java
@@ -113,7 +113,7 @@ public class HandleUtilityClass extends EclipseAnnotationHandler<UtilityClass> {
if (typeNode.up().getKind() == Kind.COMPILATION_UNIT) markStatic = false;
if (markStatic && typeNode.up().getKind() == Kind.TYPE) {
TypeDeclaration typeDecl = (TypeDeclaration) typeNode.up().get();
- if ((typeDecl.modifiers & (ClassFileConstants.AccInterface | ClassFileConstants.AccAnnotation | ClassFileConstants.AccEnum)) != 0) markStatic = false;
+ if ((typeDecl.modifiers & (ClassFileConstants.AccInterface | ClassFileConstants.AccAnnotation)) != 0) markStatic = false;
}
if (markStatic) classDecl.modifiers |= ClassFileConstants.AccStatic;
diff --git a/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSingularizer.java b/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSingularizer.java
index 392418ff..395d2e59 100755
--- a/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSingularizer.java
+++ b/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSingularizer.java
@@ -175,8 +175,10 @@ abstract class EclipseGuavaSingularizer extends EclipseSingularizer {
md.returnType = returnType;
char[] prefixedSingularName = data.getSetterPrefix().length == 0 ? data.getSingularName() : HandlerUtil.buildAccessorName(new String(data.getSetterPrefix()), new String(data.getSingularName())).toCharArray();
md.selector = fluent ? prefixedSingularName : HandlerUtil.buildAccessorName("add", new String(data.getSingularName())).toCharArray();
- md.annotations = generateSelfReturnAnnotations(deprecate, cfv, data.getSource());
-
+ Annotation[] selfReturnAnnotations = generateSelfReturnAnnotations(deprecate, cfv, data.getSource());
+ Annotation[] copyToSetterAnnotations = copyAnnotations(md, findCopyableToBuilderSingularSetterAnnotations(data.getAnnotation().up()));
+ md.annotations = concat(selfReturnAnnotations, copyToSetterAnnotations, Annotation.class);
+
if (returnStatement != null) createRelevantNonNullAnnotation(builderType, md);
data.setGeneratedByRecursive(md);
HandleNonNull.INSTANCE.fix(injectMethod(builderType, md));
@@ -213,8 +215,10 @@ abstract class EclipseGuavaSingularizer extends EclipseSingularizer {
md.returnType = returnType;
char[] prefixedSelector = data.getSetterPrefix().length == 0 ? data.getPluralName() : HandlerUtil.buildAccessorName(new String(data.getSetterPrefix()), new String(data.getPluralName())).toCharArray();
md.selector = fluent ? prefixedSelector : HandlerUtil.buildAccessorName("addAll", new String(data.getPluralName())).toCharArray();
- md.annotations = generateSelfReturnAnnotations(deprecate, cfv, data.getSource());
-
+ Annotation[] selfReturnAnnotations = generateSelfReturnAnnotations(deprecate, cfv, data.getSource());
+ Annotation[] copyToSetterAnnotations = copyAnnotations(md, findCopyableToSetterAnnotations(data.getAnnotation().up()));
+ md.annotations = concat(selfReturnAnnotations, copyToSetterAnnotations, Annotation.class);
+
if (returnStatement != null) createRelevantNonNullAnnotation(builderType, md);
data.setGeneratedByRecursive(md);
injectMethod(builderType, md);
diff --git a/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSetSingularizer.java b/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSetSingularizer.java
index 375f4e2c..deab4530 100755
--- a/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSetSingularizer.java
+++ b/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSetSingularizer.java
@@ -153,8 +153,10 @@ abstract class EclipseJavaUtilListSetSingularizer extends EclipseJavaUtilSingula
md.returnType = returnType;
char[] prefixedSingularName = data.getSetterPrefix().length == 0 ? data.getSingularName() : HandlerUtil.buildAccessorName(new String(data.getSetterPrefix()), new String(data.getSingularName())).toCharArray();
md.selector = fluent ? prefixedSingularName : HandlerUtil.buildAccessorName("add", new String(data.getSingularName())).toCharArray();
- md.annotations = generateSelfReturnAnnotations(deprecate, cfv, data.getSource());
-
+ Annotation[] selfReturnAnnotations = generateSelfReturnAnnotations(deprecate, cfv, data.getSource());
+ Annotation[] copyToSetterAnnotations = copyAnnotations(md, findCopyableToBuilderSingularSetterAnnotations(data.getAnnotation().up()));
+ md.annotations = concat(selfReturnAnnotations, copyToSetterAnnotations, Annotation.class);
+
if (returnStatement != null) createRelevantNonNullAnnotation(builderType, md);
data.setGeneratedByRecursive(md);
HandleNonNull.INSTANCE.fix(injectMethod(builderType, md));
@@ -189,8 +191,10 @@ abstract class EclipseJavaUtilListSetSingularizer extends EclipseJavaUtilSingula
md.returnType = returnType;
char[] prefixedSelector = data.getSetterPrefix().length == 0 ? data.getPluralName() : HandlerUtil.buildAccessorName(new String(data.getSetterPrefix()), new String(data.getPluralName())).toCharArray();
md.selector = fluent ? prefixedSelector : HandlerUtil.buildAccessorName("addAll", new String(data.getPluralName())).toCharArray();
- md.annotations = generateSelfReturnAnnotations(deprecate, cfv, data.getSource());
-
+ Annotation[] selfReturnAnnotations = generateSelfReturnAnnotations(deprecate, cfv, data.getSource());
+ Annotation[] copyToSetterAnnotations = copyAnnotations(md, findCopyableToSetterAnnotations(data.getAnnotation().up()));
+ md.annotations = concat(selfReturnAnnotations, copyToSetterAnnotations, Annotation.class);
+
if (returnStatement != null) createRelevantNonNullAnnotation(builderType, md);
data.setGeneratedByRecursive(md);
injectMethod(builderType, md);
diff --git a/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilMapSingularizer.java b/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilMapSingularizer.java
index cb7d9ed6..1a40369d 100755
--- a/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilMapSingularizer.java
+++ b/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilMapSingularizer.java
@@ -252,7 +252,9 @@ public class EclipseJavaUtilMapSingularizer extends EclipseJavaUtilSingularizer
String setterName = HandlerUtil.buildAccessorName(setterPrefix, name);
md.selector = setterName.toCharArray();
- md.annotations = generateSelfReturnAnnotations(deprecate, cfv, data.getSource());
+ Annotation[] selfReturnAnnotations = generateSelfReturnAnnotations(deprecate, cfv, data.getSource());
+ Annotation[] copyToSetterAnnotations = copyAnnotations(md, findCopyableToBuilderSingularSetterAnnotations(data.getAnnotation().up()));
+ md.annotations = concat(selfReturnAnnotations, copyToSetterAnnotations, Annotation.class);
if (returnStatement != null) createRelevantNonNullAnnotation(builderType, md);
data.setGeneratedByRecursive(md);
@@ -326,7 +328,9 @@ public class EclipseJavaUtilMapSingularizer extends EclipseJavaUtilSingularizer
String setterName = HandlerUtil.buildAccessorName(setterPrefix, name);
md.selector = setterName.toCharArray();
- md.annotations = generateSelfReturnAnnotations(deprecate, cfv, data.getSource());
+ Annotation[] selfReturnAnnotations = generateSelfReturnAnnotations(deprecate, cfv, data.getSource());
+ Annotation[] copyToSetterAnnotations = copyAnnotations(md, findCopyableToSetterAnnotations(data.getAnnotation().up()));
+ md.annotations = concat(selfReturnAnnotations, copyToSetterAnnotations, Annotation.class);
if (returnStatement != null) createRelevantNonNullAnnotation(builderType, md);
data.setGeneratedByRecursive(md);