Merge branch 'master' into jdk8check

Conflicts:
	src/core/lombok/core/Version.java
	src/core/lombok/javac/handlers/HandleConstructor.java
	test/transform/resource/messages-delombok/EqualsAndHashCodeWithSomeExistingMethods.java.messages
	test/transform/resource/messages-ecj/EqualsAndHashCodeWithSomeExistingMethods.java.messages
This commit is contained in:
Reinier Zwitserloot committed 2013-09-24 01:18:32 +02:00
commit 86a635876d
26 files changed
+287 -17

No files matched your search

@@ -70,9 +70,11 @@ public class TransformationsUtil {
* @param prefixes A list of prefixes, usually provided by the {@code Accessors} settings annotation, listing field prefixes.
* @return The base name of the field.
*/
private static CharSequence removePrefix(CharSequence fieldName, String[] prefixes) {
public static CharSequence removePrefix(CharSequence fieldName, String[] prefixes) {
if (prefixes == null || prefixes.length == 0) return fieldName;
fieldName = fieldName.toString();
outer:
for (String prefix : prefixes) {
if (prefix.length() == 0) return fieldName;
@@ -176,6 +178,7 @@ public class TransformationsUtil {
private static String toAccessorName(AnnotationValues<Accessors> accessors, CharSequence fieldName, boolean isBoolean,
String booleanPrefix, String normalPrefix, boolean adhereToFluent) {
fieldName = fieldName.toString();
if (fieldName.length() == 0) return null;
Accessors ac = accessors == null ? null : accessors.getInstance();
-1
View File
@@ -30,7 +30,6 @@ public class Version {
// Official builds always end in an even number. (Since 0.10.2).
private static final String VERSION = "0.12.1";
private static final String RELEASE_NAME = "Edgy Guinea Pig";
// private static final String RELEASE_NAME = "Angry Butterfly";
private Version() {
//Prevent instantiation
@@ -1125,6 +1125,37 @@ public class EclipseHandlerUtil {
return true;
}
public static char[] removePrefixFromField(EclipseNode field) {
String[] prefixes = null;
for (EclipseNode node : field.down()) {
if (annotationTypeMatches(Accessors.class, node)) {
prefixes = createAnnotation(Accessors.class, node).getInstance().prefix();
break;
}
}
if (prefixes == null) {
EclipseNode current = field.up();
outer:
while (current != null) {
for (EclipseNode node : current.down()) {
if (annotationTypeMatches(Accessors.class, node)) {
prefixes = createAnnotation(Accessors.class, node).getInstance().prefix();
break outer;
}
}
current = current.up();
}
}
if (prefixes != null && prefixes.length > 0) {
CharSequence newName = TransformationsUtil.removePrefix(field.getName(), prefixes);
if (newName != null) return newName.toString().toCharArray();
}
return ((FieldDeclaration) field.get()).name;
}
public static AnnotationValues<Accessors> getAccessorsForField(EclipseNode field) {
for (EclipseNode node : field.down()) {
if (annotationTypeMatches(Accessors.class, node)) {
@@ -113,7 +113,7 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
// non-final fields final, but @Value's handler hasn't done this yet, so we have to do this math ourselves.
// Value will only skip making a field final if it has an explicit @NonFinal annotation, so we check for that.
if (fd.initialization != null && valuePresent && !hasAnnotation(NonFinal.class, fieldNode)) continue;
namesOfParameters.add(fd.name);
namesOfParameters.add(removePrefixFromField(fieldNode));
typesOfParameters.add(fd.type);
fields.add(fieldNode);
}
@@ -230,7 +230,8 @@ public class HandleConstructor {
int ctr = 0;
for (EclipseNode field : fields) {
fieldNames.expressions[ctr] = new StringLiteral(field.getName().toCharArray(), pS, pE, 0);
char[] fieldName = removePrefixFromField(field);
fieldNames.expressions[ctr] = new StringLiteral(fieldName, pS, pE, 0);
setGeneratedBy(fieldNames.expressions[ctr], source);
ctr++;
}
@@ -273,15 +274,17 @@ public class HandleConstructor {
for (EclipseNode fieldNode : fields) {
FieldDeclaration field = (FieldDeclaration) fieldNode.get();
FieldReference thisX = new FieldReference(field.name, p);
char[] rawName = field.name;
char[] fieldName = removePrefixFromField(fieldNode);
FieldReference thisX = new FieldReference(rawName, p);
thisX.receiver = new ThisReference((int)(p >> 32), (int)p);
SingleNameReference assignmentNameRef = new SingleNameReference(field.name, p);
SingleNameReference assignmentNameRef = new SingleNameReference(fieldName, p);
Assignment assignment = new Assignment(thisX, assignmentNameRef, (int)p);
assignment.sourceStart = (int)(p >> 32); assignment.sourceEnd = assignment.statementEnd = (int)(p >> 32);
assigns.add(assignment);
long fieldPos = (((long)field.sourceStart) << 32) | field.sourceEnd;
Argument parameter = new Argument(field.name, fieldPos, copyType(field.type, source), Modifier.FINAL);
Argument parameter = new Argument(fieldName, fieldPos, copyType(field.type, source), Modifier.FINAL);
Annotation[] nonNulls = findAnnotations(field, TransformationsUtil.NON_NULL_PATTERN);
Annotation[] nullables = findAnnotations(field, TransformationsUtil.NULLABLE_PATTERN);
if (nonNulls.length != 0) {
@@ -221,7 +221,7 @@ public class HandleEqualsAndHashCode extends EclipseAnnotationHandler<EqualsAndH
// The user code couldn't possibly (barring really weird subclassing shenanigans) be in a shippable state anyway; the implementations of these 3 methods are
// all inter-related and should be written by the same entity.
String msg = String.format("Not generating %s: One of equals, hashCode, and canEqual exists. " +
"You should either write all of these are none of these (in the latter case, lombok generates them).",
"You should either write all of these or none of these (in the latter case, lombok generates them).",
equalsExists == MemberExistsResult.NOT_EXISTS && hashCodeExists == MemberExistsResult.NOT_EXISTS ? "equals and hashCode" :
equalsExists == MemberExistsResult.NOT_EXISTS ? "equals" : "hashCode");
errorNode.addWarning(msg);
@@ -82,6 +82,11 @@ public class NonNullHandler extends EclipseAnnotationHandler<NonNull> {
if (isGenerated(declaration)) return;
if (declaration.isAbstract()) {
annotationNode.addWarning("@NonNull is meaningless on a parameter of an abstract method.");
return;
}
// Possibly, if 'declaration instanceof ConstructorDeclaration', fetch declaration.constructorCall, search it for any references to our parameter,
// and if they exist, create a new method in the class: 'private static <T> T lombok$nullCheck(T expr, String msg) {if (expr == null) throw NPE; return expr;}' and
// wrap all references to it in the super/this to a call to this method.
@@ -28,11 +28,13 @@ import org.mangosdk.spi.ProviderFor;
import com.sun.tools.javac.tree.JCTree.JCAnnotation;
import lombok.core.AnnotationValues;
import lombok.core.HandlerPriority;
import lombok.experimental.Accessors;
import lombok.javac.JavacAnnotationHandler;
import lombok.javac.JavacNode;
@ProviderFor(JavacAnnotationHandler.class)
@HandlerPriority(65536)
public class HandleAccessors extends JavacAnnotationHandler<Accessors> {
@Override public void handle(AnnotationValues<Accessors> annotation, JCAnnotation ast, JavacNode annotationNode) {
// Accessors itself is handled by HandleGetter/Setter; this is just to ensure that the annotation is removed
@@ -107,7 +107,7 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
// non-final fields final, but @Value's handler hasn't done this yet, so we have to do this math ourselves.
// Value will only skip making a field final if it has an explicit @NonFinal annotation, so we check for that.
if (fd.init != null && valuePresent && !hasAnnotation(NonFinal.class, fieldNode)) continue;
namesOfParameters.add(fd.name);
namesOfParameters.add(removePrefixFromField(fieldNode));
typesOfParameters.add(fd.vartype);
allFields.append(fieldNode);
}
@@ -52,6 +52,7 @@ import com.sun.tools.javac.tree.JCTree.JCTypeParameter;
import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
import com.sun.tools.javac.util.List;
import com.sun.tools.javac.util.ListBuffer;
import com.sun.tools.javac.util.Name;
public class HandleConstructor {
@ProviderFor(JavacAnnotationHandler.class)
@@ -210,7 +211,8 @@ public class HandleConstructor {
JCExpression constructorPropertiesType = chainDots(node, "java", "beans", "ConstructorProperties");
ListBuffer<JCExpression> fieldNames = ListBuffer.lb();
for (JavacNode field : fields) {
fieldNames.append(maker.Literal(field.getName()));
Name fieldName = removePrefixFromField(field);
fieldNames.append(maker.Literal(fieldName.toString()));
}
JCExpression fieldNamesArray = maker.NewArray(null, List.<JCExpression>nil(), fieldNames.toList());
JCAnnotation annotation = maker.Annotation(constructorPropertiesType, List.of(fieldNamesArray));
@@ -229,12 +231,14 @@ public class HandleConstructor {
for (JavacNode fieldNode : fields) {
JCVariableDecl field = (JCVariableDecl) fieldNode.get();
Name fieldName = removePrefixFromField(fieldNode);
Name rawName = field.name;
List<JCAnnotation> nonNulls = findAnnotations(fieldNode, TransformationsUtil.NON_NULL_PATTERN);
List<JCAnnotation> nullables = findAnnotations(fieldNode, TransformationsUtil.NULLABLE_PATTERN);
JCVariableDecl param = maker.VarDef(maker.Modifiers(Flags.FINAL | Flags.PARAMETER, nonNulls.appendList(nullables)), field.name, field.vartype, null);
JCVariableDecl param = maker.VarDef(maker.Modifiers(Flags.FINAL | Flags.PARAMETER, nonNulls.appendList(nullables)), fieldName, field.vartype, null);
params.append(param);
JCFieldAccess thisX = maker.Select(maker.Ident(fieldNode.toName("this")), field.name);
JCAssign assign = maker.Assign(thisX, maker.Ident(field.name));
JCFieldAccess thisX = maker.Select(maker.Ident(fieldNode.toName("this")), rawName);
JCAssign assign = maker.Assign(thisX, maker.Ident(fieldName));
assigns.append(maker.Exec(assign));
if (!nonNulls.isEmpty()) {
@@ -289,12 +293,13 @@ public class HandleConstructor {
for (JavacNode fieldNode : fields) {
JCVariableDecl field = (JCVariableDecl) fieldNode.get();
Name fieldName = removePrefixFromField(fieldNode);
JCExpression pType = cloneType(maker, field.vartype, source);
List<JCAnnotation> nonNulls = findAnnotations(fieldNode, TransformationsUtil.NON_NULL_PATTERN);
List<JCAnnotation> nullables = findAnnotations(fieldNode, TransformationsUtil.NULLABLE_PATTERN);
JCVariableDecl param = maker.VarDef(maker.Modifiers(Flags.FINAL | Flags.PARAMETER, nonNulls.appendList(nullables)), field.name, pType, null);
JCVariableDecl param = maker.VarDef(maker.Modifiers(Flags.FINAL | Flags.PARAMETER, nonNulls.appendList(nullables)), fieldName, pType, null);
params.append(param);
args.append(maker.Ident(field.name));
args.append(maker.Ident(fieldName));
}
JCReturn returnStatement = maker.Return(maker.NewClass(null, List.<JCExpression>nil(), constructorType, args.toList(), null));
JCBlock body = maker.Block(0, List.<JCStatement>of(returnStatement));
@@ -195,7 +195,7 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas
// The user code couldn't possibly (barring really weird subclassing shenanigans) be in a shippable state anyway; the implementations of these 3 methods are
// all inter-related and should be written by the same entity.
String msg = String.format("Not generating %s: One of equals, hashCode, and canEqual exists. " +
"You should either write all of these are none of these (in the latter case, lombok generates them).",
"You should either write all of these or none of these (in the latter case, lombok generates them).",
equalsExists == MemberExistsResult.NOT_EXISTS && hashCodeExists == MemberExistsResult.NOT_EXISTS ? "equals and hashCode" :
equalsExists == MemberExistsResult.NOT_EXISTS ? "equals" : "hashCode");
source.addWarning(msg);
@@ -460,6 +460,37 @@ public class JavacHandlerUtil {
return varType != null && varType.toString().equals("boolean");
}
public static Name removePrefixFromField(JavacNode field) {
String[] prefixes = null;
for (JavacNode node : field.down()) {
if (annotationTypeMatches(Accessors.class, node)) {
prefixes = createAnnotation(Accessors.class, node).getInstance().prefix();
break;
}
}
if (prefixes == null) {
JavacNode current = field.up();
outer:
while (current != null) {
for (JavacNode node : current.down()) {
if (annotationTypeMatches(Accessors.class, node)) {
prefixes = createAnnotation(Accessors.class, node).getInstance().prefix();
break outer;
}
}
current = current.up();
}
}
if (prefixes != null && prefixes.length > 0) {
CharSequence newName = TransformationsUtil.removePrefix(field.getName(), prefixes);
if (newName != null) return field.toName(newName.toString());
}
return ((JCVariableDecl) field.get()).name;
}
public static AnnotationValues<Accessors> getAccessorsForField(JavacNode field) {
for (JavacNode node : field.down()) {
if (annotationTypeMatches(Accessors.class, node)) {
@@ -79,6 +79,11 @@ public class NonNullHandler extends JavacAnnotationHandler<NonNull> {
if (JavacHandlerUtil.isGenerated(declaration)) return;
if (declaration.body == null) {
annotationNode.addWarning("@NonNull is meaningless on a parameter of an abstract method.");
return;
}
// Possibly, if 'declaration instanceof ConstructorDeclaration', fetch declaration.constructorCall, search it for any references to our parameter,
// and if they exist, create a new method in the class: 'private static <T> T lombok$nullCheck(T expr, String msg) {if (expr == null) throw NPE; return expr;}' and
// wrap all references to it in the super/this to a call to this method.
@@ -0,0 +1,65 @@
class BuilderWithAccessors {
private final int plower;
private final int pUpper;
private int _foo;
private int __bar;
@java.lang.SuppressWarnings("all")
BuilderWithAccessors(final int plower, final int upper, final int foo, final int _bar) {
this.plower = plower;
this.pUpper = upper;
this._foo = foo;
this.__bar = _bar;
}
@java.lang.SuppressWarnings("all")
public static class BuilderWithAccessorsBuilder {
private int plower;
private int upper;
private int foo;
private int _bar;
@java.lang.SuppressWarnings("all")
BuilderWithAccessorsBuilder() {
}
@java.lang.SuppressWarnings("all")
public BuilderWithAccessorsBuilder plower(final int plower) {
this.plower = plower;
return this;
}
@java.lang.SuppressWarnings("all")
public BuilderWithAccessorsBuilder upper(final int upper) {
this.upper = upper;
return this;
}
@java.lang.SuppressWarnings("all")
public BuilderWithAccessorsBuilder foo(final int foo) {
this.foo = foo;
return this;
}
@java.lang.SuppressWarnings("all")
public BuilderWithAccessorsBuilder _bar(final int _bar) {
this._bar = _bar;
return this;
}
@java.lang.SuppressWarnings("all")
public BuilderWithAccessors build() {
return new BuilderWithAccessors(plower, upper, foo, _bar);
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
public java.lang.String toString() {
return "BuilderWithAccessors.BuilderWithAccessorsBuilder(plower=" + this.plower + ", upper=" + this.upper + ", foo=" + this.foo + ", _bar=" + this._bar + ")";
}
}
@java.lang.SuppressWarnings("all")
public static BuilderWithAccessorsBuilder builder() {
return new BuilderWithAccessorsBuilder();
}
}
@@ -0,0 +1,15 @@
class ConstructorsWithAccessors {
int plower;
int pUpper;
int _huh;
int __huh2;
@java.beans.ConstructorProperties({"plower", "upper", "huh", "_huh2"})
@java.lang.SuppressWarnings("all")
public ConstructorsWithAccessors(final int plower, final int upper, final int huh, final int _huh2) {
this.plower = plower;
this.pUpper = upper;
this._huh = huh;
this.__huh2 = _huh2;
}
}
@@ -0,0 +1,10 @@
abstract class NonNullOnParameterAbstract {
public void test(@lombok.NonNull String arg) {
if (arg == null) {
throw new java.lang.NullPointerException("arg");
}
System.out.println("Hey");
}
public abstract void test2(@lombok.NonNull String arg);
}
@@ -0,0 +1,47 @@
@lombok.experimental.Builder @lombok.experimental.Accessors(prefix = {"p", "_"}) class BuilderWithAccessors {
public static @java.lang.SuppressWarnings("all") class BuilderWithAccessorsBuilder {
private int plower;
private int upper;
private int foo;
private int _bar;
@java.lang.SuppressWarnings("all") BuilderWithAccessorsBuilder() {
super();
}
public @java.lang.SuppressWarnings("all") BuilderWithAccessorsBuilder plower(final int plower) {
this.plower = plower;
return this;
}
public @java.lang.SuppressWarnings("all") BuilderWithAccessorsBuilder upper(final int upper) {
this.upper = upper;
return this;
}
public @java.lang.SuppressWarnings("all") BuilderWithAccessorsBuilder foo(final int foo) {
this.foo = foo;
return this;
}
public @java.lang.SuppressWarnings("all") BuilderWithAccessorsBuilder _bar(final int _bar) {
this._bar = _bar;
return this;
}
public @java.lang.SuppressWarnings("all") BuilderWithAccessors build() {
return new BuilderWithAccessors(plower, upper, foo, _bar);
}
public @java.lang.Override @java.lang.SuppressWarnings("all") java.lang.String toString() {
return (((((((("BuilderWithAccessors.BuilderWithAccessorsBuilder(plower=" + this.plower) + ", upper=") + this.upper) + ", foo=") + this.foo) + ", _bar=") + this._bar) + ")");
}
}
private final int plower;
private final int pUpper;
private int _foo;
private int __bar;
@java.lang.SuppressWarnings("all") BuilderWithAccessors(final int plower, final int upper, final int foo, final int _bar) {
super();
this.plower = plower;
this.pUpper = upper;
this._foo = foo;
this.__bar = _bar;
}
public static @java.lang.SuppressWarnings("all") BuilderWithAccessorsBuilder builder() {
return new BuilderWithAccessorsBuilder();
}
}
@@ -0,0 +1,13 @@
@lombok.AllArgsConstructor @lombok.experimental.Accessors(prefix = {"p", "_"}) class ConstructorsWithAccessors {
int plower;
int pUpper;
int _huh;
int __huh2;
public @java.beans.ConstructorProperties({"plower", "upper", "huh", "_huh2"}) @java.lang.SuppressWarnings("all") ConstructorsWithAccessors(final int plower, final int upper, final int huh, final int _huh2) {
super();
this.plower = plower;
this.pUpper = upper;
this._huh = huh;
this.__huh2 = _huh2;
}
}
@@ -0,0 +1,13 @@
abstract class NonNullOnParameterAbstract {
NonNullOnParameterAbstract() {
super();
}
public void test(@lombok.NonNull String arg) {
if ((arg == null))
{
throw new java.lang.NullPointerException("arg");
}
System.out.println("Hey");
}
public abstract void test2(@lombok.NonNull String arg);
}
@@ -0,0 +1,7 @@
@lombok.experimental.Builder @lombok.experimental.Accessors(prefix={"p", "_"})
class BuilderWithAccessors {
private final int plower;
private final int pUpper;
private int _foo;
private int __bar;
}
@@ -0,0 +1,6 @@
@lombok.AllArgsConstructor @lombok.experimental.Accessors(prefix={"p", "_"}) class ConstructorsWithAccessors {
int plower;
int pUpper;
int _huh;
int __huh2;
}
@@ -0,0 +1,7 @@
abstract class NonNullOnParameterAbstract {
public void test(@lombok.NonNull String arg) {
System.out.println("Hey");
}
public abstract void test2(@lombok.NonNull String arg);
}
@@ -0,0 +1 @@
6:36 @NonNull is meaningless on a parameter of an abstract method.
@@ -0,0 +1 @@
6:154 @NonNull is meaningless on a parameter of an abstract method.
@@ -0,0 +1 @@
9:36 @NonNull is meaningless on a parameter of an abstract method.
+1 -1
View File
@@ -4,7 +4,7 @@ public class GetterLazyExample {
public double[] getCached() {
java.lang.Object value = this.cached.get();
if (value == null) {
synchronized(value) {
synchronized(this.cached) {
value = this.cached.get();
if (value == null) {
final double[] actualValue = expensive();