do null checks after assignment so that default==null is covered; only

assign value once so that final fields work (ecj)
This commit is contained in:
Jan Rieke committed 2018-08-16 18:31:19 +02:00
1 parent 31aef5219d
commit 76f6013b59
2 files changed
+109 -15

No files matched your search

@@ -48,7 +48,6 @@ import org.eclipse.jdt.internal.compiler.ast.FieldReference;
import org.eclipse.jdt.internal.compiler.ast.IfStatement;
import org.eclipse.jdt.internal.compiler.ast.MessageSend;
import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.OperatorIds;
import org.eclipse.jdt.internal.compiler.ast.ParameterizedQualifiedTypeReference;
import org.eclipse.jdt.internal.compiler.ast.ParameterizedSingleTypeReference;
import org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference;
@@ -61,7 +60,6 @@ import org.eclipse.jdt.internal.compiler.ast.ThisReference;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.eclipse.jdt.internal.compiler.ast.TypeParameter;
import org.eclipse.jdt.internal.compiler.ast.TypeReference;
import org.eclipse.jdt.internal.compiler.ast.UnaryExpression;
import org.eclipse.jdt.internal.compiler.ast.Wildcard;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
@@ -456,7 +454,6 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
constructor.arguments = new Argument[] {new Argument("b".toCharArray(), p, builderType, Modifier.FINAL)};
List<Statement> statements = new ArrayList<Statement>();
List<Statement> nullChecks = new ArrayList<Statement>();
for (BuilderFieldData fieldNode : builderFields) {
char[] fieldName = removePrefixFromField(fieldNode.originalFieldNode);
@@ -475,7 +472,6 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
assignmentExpr = new QualifiedNameReference(variableInBuilder, positions, s, e);
}
Statement assignment = new Assignment(fieldInThis, assignmentExpr, (int) p);
statements.add(assignment);
// In case of @Builder.Default, set the value to the default if it was NOT set in the builder.
if (fieldNode.nameOfSetFlag != null) {
@@ -483,29 +479,30 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
long[] positions = new long[] {p, p};
QualifiedNameReference setVariableInBuilderRef = new QualifiedNameReference(setVariableInBuilder, positions, s, e);
MessageSend inv = new MessageSend();
inv.sourceStart = source.sourceStart;
inv.sourceEnd = source.sourceEnd;
inv.receiver = new SingleNameReference(((TypeDeclaration) typeNode.get()).name, 0L);
inv.selector = fieldNode.nameOfDefaultProvider;
inv.typeArguments = typeParameterNames(((TypeDeclaration) typeNode.get()).typeParameters);
MessageSend defaultMethodCall = new MessageSend();
defaultMethodCall.sourceStart = source.sourceStart;
defaultMethodCall.sourceEnd = source.sourceEnd;
defaultMethodCall.receiver = new SingleNameReference(((TypeDeclaration) typeNode.get()).name, 0L);
defaultMethodCall.selector = fieldNode.nameOfDefaultProvider;
defaultMethodCall.typeArguments = typeParameterNames(((TypeDeclaration) typeNode.get()).typeParameters);
assignment = new Assignment(fieldInThis, inv, (int) p);
IfStatement ifBlockForDefault = new IfStatement(new UnaryExpression(setVariableInBuilderRef, OperatorIds.NOT), assignment, s, e);
Statement defaultAssignment = new Assignment(fieldInThis, defaultMethodCall, (int) p);
IfStatement ifBlockForDefault = new IfStatement(setVariableInBuilderRef, assignment, defaultAssignment, s, e);
statements.add(ifBlockForDefault);
} else {
statements.add(assignment);
}
Annotation[] nonNulls = findAnnotations((FieldDeclaration)fieldNode.originalFieldNode.get(), NON_NULL_PATTERN);
if (nonNulls.length != 0) {
Statement nullCheck = generateNullCheck((FieldDeclaration)fieldNode.originalFieldNode.get(), sourceNode);
if (nullCheck != null) {
nullChecks.add(nullCheck);
statements.add(nullCheck);
}
}
}
nullChecks.addAll(statements);
constructor.statements = nullChecks.isEmpty() ? null : nullChecks.toArray(new Statement[nullChecks.size()]);
constructor.statements = statements.isEmpty() ? null : statements.toArray(new Statement[statements.size()]);
constructor.traverse(new SetGeneratedByVisitor(source), typeDeclaration.scope);
@@ -0,0 +1,97 @@
import java.util.List;
public class SuperBuilderWithNonNull {
public static @lombok.experimental.SuperBuilder class Parent {
public static abstract @java.lang.SuppressWarnings("all") class ParentBuilder<C extends Parent, B extends ParentBuilder<C, B>> {
private @java.lang.SuppressWarnings("all") String nonNullParentField;
private @java.lang.SuppressWarnings("all") boolean nonNullParentField$set;
public ParentBuilder() {
super();
}
protected abstract @java.lang.SuppressWarnings("all") B self();
public abstract @java.lang.SuppressWarnings("all") C build();
public @java.lang.SuppressWarnings("all") B nonNullParentField(final String nonNullParentField) {
this.nonNullParentField = nonNullParentField;
nonNullParentField$set = true;
return self();
}
public @java.lang.Override @java.lang.SuppressWarnings("all") java.lang.String toString() {
return (("SuperBuilderWithNonNull.Parent.ParentBuilder(nonNullParentField=" + this.nonNullParentField) + ")");
}
}
private static final @java.lang.SuppressWarnings("all") class ParentBuilderImpl extends ParentBuilder<Parent, ParentBuilderImpl> {
private ParentBuilderImpl() {
super();
}
protected @java.lang.Override @java.lang.SuppressWarnings("all") ParentBuilderImpl self() {
return this;
}
public @java.lang.Override @java.lang.SuppressWarnings("all") Parent build() {
return new Parent(this);
}
}
final @lombok.NonNull @lombok.Builder.Default String nonNullParentField;
private static @java.lang.SuppressWarnings("all") String $default$nonNullParentField() {
return "default";
}
protected @java.lang.SuppressWarnings("all") Parent(final ParentBuilder<?, ?> b) {
super();
if (b.nonNullParentField$set)
this.nonNullParentField = b.nonNullParentField;
else
this.nonNullParentField = Parent.$default$nonNullParentField();
if ((nonNullParentField == null))
{
throw new java.lang.NullPointerException("nonNullParentField is marked @NonNull but is null");
}
}
public static @java.lang.SuppressWarnings("all") ParentBuilder<?, ?> builder() {
return new ParentBuilderImpl();
}
}
public static @lombok.experimental.SuperBuilder class Child extends Parent {
public static abstract @java.lang.SuppressWarnings("all") class ChildBuilder<C extends Child, B extends ChildBuilder<C, B>> extends Parent.ParentBuilder<C, B> {
private @java.lang.SuppressWarnings("all") String nonNullChildField;
public ChildBuilder() {
super();
}
protected abstract @java.lang.Override @java.lang.SuppressWarnings("all") B self();
public abstract @java.lang.Override @java.lang.SuppressWarnings("all") C build();
public @java.lang.SuppressWarnings("all") B nonNullChildField(final String nonNullChildField) {
this.nonNullChildField = nonNullChildField;
return self();
}
public @java.lang.Override @java.lang.SuppressWarnings("all") java.lang.String toString() {
return (((("SuperBuilderWithNonNull.Child.ChildBuilder(super=" + super.toString()) + ", nonNullChildField=") + this.nonNullChildField) + ")");
}
}
private static final @java.lang.SuppressWarnings("all") class ChildBuilderImpl extends ChildBuilder<Child, ChildBuilderImpl> {
private ChildBuilderImpl() {
super();
}
protected @java.lang.Override @java.lang.SuppressWarnings("all") ChildBuilderImpl self() {
return this;
}
public @java.lang.Override @java.lang.SuppressWarnings("all") Child build() {
return new Child(this);
}
}
@lombok.NonNull String nonNullChildField;
protected @java.lang.SuppressWarnings("all") Child(final ChildBuilder<?, ?> b) {
super(b);
this.nonNullChildField = b.nonNullChildField;
if ((nonNullChildField == null))
{
throw new java.lang.NullPointerException("nonNullChildField is marked @NonNull but is null");
}
}
public static @java.lang.SuppressWarnings("all") ChildBuilder<?, ?> builder() {
return new ChildBuilderImpl();
}
}
public SuperBuilderWithNonNull() {
super();
}
public static void test() {
Child x = Child.builder().nonNullChildField("child").nonNullParentField("parent").build();
}
}