aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/lombok/Builder.java2
-rw-r--r--src/core/lombok/EqualsAndHashCode.java9
-rw-r--r--src/core/lombok/NonNull.java13
-rw-r--r--src/core/lombok/ToString.java15
-rwxr-xr-xsrc/core/lombok/core/AST.java11
-rw-r--r--src/core/lombok/core/CleanupRegistry.java4
-rw-r--r--src/core/lombok/core/LombokNode.java9
-rw-r--r--src/core/lombok/core/configuration/NullCheckExceptionType.java24
-rw-r--r--src/core/lombok/core/handlers/HandlerUtil.java8
-rw-r--r--src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java53
-rwxr-xr-xsrc/core/lombok/eclipse/handlers/HandleBuilder.java26
-rw-r--r--src/core/lombok/eclipse/handlers/HandleNonNull.java37
-rwxr-xr-xsrc/core/lombok/eclipse/handlers/HandleSuperBuilder.java27
-rw-r--r--src/core/lombok/experimental/FieldNameConstants.java2
-rw-r--r--src/core/lombok/experimental/SuperBuilder.java2
-rw-r--r--src/core/lombok/javac/handlers/HandleBuilder.java26
-rw-r--r--src/core/lombok/javac/handlers/HandleNonNull.java25
-rw-r--r--src/core/lombok/javac/handlers/HandleSuperBuilder.java23
-rw-r--r--src/core/lombok/javac/handlers/JavacHandlerUtil.java69
-rwxr-xr-xsrc/delombok/lombok/delombok/Delombok.java1
-rw-r--r--src/delombok/lombok/delombok/PrettyPrinter.java6
21 files changed, 266 insertions, 126 deletions
diff --git a/src/core/lombok/Builder.java b/src/core/lombok/Builder.java
index ea94eb4e..c83b3670 100644
--- a/src/core/lombok/Builder.java
+++ b/src/core/lombok/Builder.java
@@ -120,7 +120,7 @@ public @interface Builder {
@Retention(SOURCE)
public @interface Default {}
- /** @return Name of the method that creates a new builder instance. Default: {@code builder}. */
+ /** @return Name of the method that creates a new builder instance. Default: {@code builder}. If the empty string, suppress generating the {@code builder} method. */
String builderMethodName() default "builder";
/** @return Name of the method in the builder class that creates an instance of your {@code @Builder}-annotated class. */
diff --git a/src/core/lombok/EqualsAndHashCode.java b/src/core/lombok/EqualsAndHashCode.java
index b2fc672d..e752165c 100644
--- a/src/core/lombok/EqualsAndHashCode.java
+++ b/src/core/lombok/EqualsAndHashCode.java
@@ -97,6 +97,8 @@ public @interface EqualsAndHashCode {
/**
* Only include fields and methods explicitly marked with {@code @EqualsAndHashCode.Include}.
* Normally, all (non-static, non-transient) fields are included by default.
+ *
+ * @return If {@code true}, don't include non-static non-transient fields automatically (default: {@code false}).
*/
boolean onlyExplicitlyIncluded() default false;
@@ -113,7 +115,12 @@ public @interface EqualsAndHashCode {
@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.SOURCE)
public @interface Include {
- /** Defaults to the method name of the annotated member. If on a method and the name equals the name of a default-included field, this member takes its place. */
+ /**
+ * Defaults to the method name of the annotated member.
+ * If on a method and the name equals the name of a default-included field, this member takes its place.
+ *
+ * @return If present, this method serves as replacement for the named field.
+ */
String replaces() default "";
}
}
diff --git a/src/core/lombok/NonNull.java b/src/core/lombok/NonNull.java
index caf6ed05..ba8c24a4 100644
--- a/src/core/lombok/NonNull.java
+++ b/src/core/lombok/NonNull.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2013 The Project Lombok Authors.
+ * Copyright (C) 2009-2019 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
@@ -30,16 +30,7 @@ import java.lang.annotation.Target;
/**
* If put on a parameter, lombok will insert a null-check at the start of the method / constructor's body, throwing a
* {@code NullPointerException} with the parameter's name as message. If put on a field, any generated method assigning
- * a value to this field will also produce these nullchecks.
- * <p>
- * Note that any annotation named {@code NonNull} with any casing and any package will result in nullchecks produced for
- * generated methods (and the annotation will be copied to the getter return type and any parameters of generated methods),
- * but <em>only</em> this annotation, if present on a parameter, will result in a null check inserted into your otherwise
- * handwritten method.
- *
- * WARNING: If the java community ever does decide on supporting a single {@code @NonNull} annotation (for example via JSR305), then
- * this annotation will <strong>be deleted</strong> from the lombok package. If the need to update an import statement scares
- * you, you should use your own annotation named {@code @NonNull} instead of this one.
+ * a value to this field will also produce these null-checks.
*/
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.LOCAL_VARIABLE, ElementType.TYPE_USE})
@Retention(RetentionPolicy.CLASS)
diff --git a/src/core/lombok/ToString.java b/src/core/lombok/ToString.java
index ae3f071f..34418a2f 100644
--- a/src/core/lombok/ToString.java
+++ b/src/core/lombok/ToString.java
@@ -83,6 +83,8 @@ public @interface ToString {
/**
* Only include fields and methods explicitly marked with {@code @ToString.Include}.
* Normally, all (non-static) fields are included by default.
+ *
+ * @return If {@code true}, don't include non-static fields automatically (default: {@code false}).
*/
boolean onlyExplicitlyIncluded() default false;
@@ -102,10 +104,19 @@ public @interface ToString {
// /** If true and the return value is {@code null}, omit this member entirely from the {@code toString} output. */
// boolean skipNull() default false; // -- We'll add it later, it requires a complete rework on the toString code we generate.
- /** Higher ranks are printed first. Members of the same rank are printed in the order they appear in the source file. */
+ /**
+ * Higher ranks are printed first. Members of the same rank are printed in the order they appear in the source file.
+ *
+ * @return ordering within the generating {@code toString()}; higher numbers are printed first.
+ */
int rank() default 0;
- /** Defaults to the field / method name of the annotated member. If the name equals the name of a default-included field, this member takes its place. */
+ /**
+ * Defaults to the field / method name of the annotated member.
+ * If the name equals the name of a default-included field, this member takes its place.
+ *
+ * @return The name to show in the generated {@code toString()}. Also, if this annotation is on a method and the name matches an existing field, it replaces that field.
+ */
String name() default "";
}
}
diff --git a/src/core/lombok/core/AST.java b/src/core/lombok/core/AST.java
index 78761f46..9f3a471f 100755
--- a/src/core/lombok/core/AST.java
+++ b/src/core/lombok/core/AST.java
@@ -60,6 +60,7 @@ public abstract class AST<A extends AST<A, L, N>, L extends LombokNode<A, L, N>,
private final String fileName;
private final String packageDeclaration;
private final ImportList imports;
+ private TypeResolver importsAsResolver;
Map<N, N> identityDetector = new IdentityHashMap<N, N>();
private Map<N, L> nodeMap = new IdentityHashMap<N, L>();
private boolean changed = false;
@@ -112,14 +113,20 @@ public abstract class AST<A extends AST<A, L, N>, L extends LombokNode<A, L, N>,
/**
* Return the contents of each non-static import statement on this AST's top (Compilation Unit) node.
- *
- * Example: "java.util.IOException".
*/
public final ImportList getImportList() {
return imports;
}
/**
+ * Return the contents of each non-static import statement on this AST's top (Compilation Unit) node, packed into a (cached) TypeResolver.
+ */
+ public final TypeResolver getImportListAsTypeResolver() {
+ if (importsAsResolver != null) return importsAsResolver;
+ return importsAsResolver = new TypeResolver(getImportList());
+ }
+
+ /**
* Puts the given node in the map so that javac/Eclipse's own internal AST object can be translated to
* an AST.Node object. Also registers the object as visited to avoid endless loops.
*/
diff --git a/src/core/lombok/core/CleanupRegistry.java b/src/core/lombok/core/CleanupRegistry.java
index 82a52fdb..d6aee477 100644
--- a/src/core/lombok/core/CleanupRegistry.java
+++ b/src/core/lombok/core/CleanupRegistry.java
@@ -21,8 +21,8 @@
*/
package lombok.core;
-import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
public class CleanupRegistry {
private static final class CleanupKey {
@@ -48,7 +48,7 @@ public class CleanupRegistry {
}
}
- private final Map<CleanupKey, CleanupTask> tasks = new ConcurrentHashMap<CleanupKey, CleanupTask>();
+ private final ConcurrentMap<CleanupKey, CleanupTask> tasks = new ConcurrentHashMap<CleanupKey, CleanupTask>();
public void registerTask(String key, Object target, CleanupTask task) {
CleanupKey ck = new CleanupKey(key, target);
diff --git a/src/core/lombok/core/LombokNode.java b/src/core/lombok/core/LombokNode.java
index ae8fd325..843a78f0 100644
--- a/src/core/lombok/core/LombokNode.java
+++ b/src/core/lombok/core/LombokNode.java
@@ -97,6 +97,15 @@ public abstract class LombokNode<A extends AST<A, L, N>, L extends LombokNode<A,
}
/**
+ * Convenient shortcut to the owning ast object's {@code getImportListAsTypeResolver} method.
+ *
+ * @see AST#getImportListAsTypeResolver()
+ */
+ public TypeResolver getImportListAsTypeResolver() {
+ return getAst().getImportListAsTypeResolver();
+ }
+
+ /**
* See {@link #isStructurallySignificant}.
*/
protected abstract boolean calculateIsStructurallySignificant(N parent);
diff --git a/src/core/lombok/core/configuration/NullCheckExceptionType.java b/src/core/lombok/core/configuration/NullCheckExceptionType.java
index c4bb71f2..d226c0a8 100644
--- a/src/core/lombok/core/configuration/NullCheckExceptionType.java
+++ b/src/core/lombok/core/configuration/NullCheckExceptionType.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014-2018 The Project Lombok Authors.
+ * Copyright (C) 2014-2019 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
@@ -22,27 +22,27 @@
package lombok.core.configuration;
-@ExampleValueString("[NullPointerException | IllegalArgumentException]")
+@ExampleValueString("[NullPointerException | IllegalArgumentException | Assertion]")
public enum NullCheckExceptionType {
ILLEGAL_ARGUMENT_EXCEPTION {
- public String toExceptionMessage(String fieldName) {
- return fieldName + " is marked @NonNull but is null";
- }
-
@Override public String getExceptionType() {
return "java.lang.IllegalArgumentException";
}
},
NULL_POINTER_EXCEPTION {
- @Override public String toExceptionMessage(String fieldName) {
- return fieldName + " is marked @NonNull but is null";
- }
-
- public String getExceptionType() {
+ @Override public String getExceptionType() {
return "java.lang.NullPointerException";
}
+ },
+ ASSERTION {
+ @Override public String getExceptionType() {
+ return null;
+ }
};
- public abstract String toExceptionMessage(String fieldName);
+ public String toExceptionMessage(String fieldName) {
+ return fieldName + " is marked non-null but is null";
+ }
+
public abstract String getExceptionType();
}
diff --git a/src/core/lombok/core/handlers/HandlerUtil.java b/src/core/lombok/core/handlers/HandlerUtil.java
index d0092b53..64d17cd9 100644
--- a/src/core/lombok/core/handlers/HandlerUtil.java
+++ b/src/core/lombok/core/handlers/HandlerUtil.java
@@ -84,8 +84,7 @@ public class HandlerUtil {
"com.sun.istack.internal.NotNull",
"edu.umd.cs.findbugs.annotations.NonNull",
"javax.annotation.Nonnull",
- // The field might contain a null value until it is persisted.
- // "javax.validation.constraints.NotNull",
+ // "javax.validation.constraints.NotNull", // The field might contain a null value until it is persisted.
"lombok.NonNull",
"org.checkerframework.checker.nullness.qual.NonNull",
"org.eclipse.jdt.annotation.NonNull",
@@ -105,8 +104,8 @@ public class HandlerUtil {
"javax.annotation.Nonnull",
"javax.annotation.Nullable",
"lombok.NonNull",
- // To update Checker Framework annotations, run:
- // grep --recursive --files-with-matches -e '^@Target\b.*TYPE_USE' $CHECKERFRAMEWORK/checker/src/main/java $CHECKERFRAMEWORK/framework/src/main/java | grep '\.java$' | sed 's/.*\/java\//\t\t\t"/' | sed 's/\.java$/",/' | sed 's/\//./g' | sort
+ // To update Checker Framework annotations, run:
+ // grep --recursive --files-with-matches -e '^@Target\b.*TYPE_USE' $CHECKERFRAMEWORK/checker/src/main/java $CHECKERFRAMEWORK/framework/src/main/java | grep '\.java$' | sed 's/.*\/java\//\t\t\t"/' | sed 's/\.java$/",/' | sed 's/\//./g' | sort
"org.checkerframework.checker.compilermsgs.qual.CompilerMessageKey",
"org.checkerframework.checker.compilermsgs.qual.CompilerMessageKeyBottom",
"org.checkerframework.checker.compilermsgs.qual.UnknownCompilerMessageKey",
@@ -293,6 +292,7 @@ public class HandlerUtil {
"org.checkerframework.common.value.qual.UnknownVal",
"org.checkerframework.framework.qual.PolyAll",
"org.checkerframework.framework.util.PurityUnqualified",
+
"org.eclipse.jdt.annotation.NonNull",
"org.eclipse.jdt.annotation.Nullable",
"org.jetbrains.annotations.NotNull",
diff --git a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java
index 9439caf3..010dc9d8 100644
--- a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java
+++ b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java
@@ -66,6 +66,7 @@ import org.eclipse.jdt.internal.compiler.ast.Annotation;
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.Block;
import org.eclipse.jdt.internal.compiler.ast.CastExpression;
import org.eclipse.jdt.internal.compiler.ast.CharLiteral;
@@ -221,14 +222,14 @@ public class EclipseHandlerUtil {
* @param typeRef A type reference to check.
*/
public static boolean typeMatches(String 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]);
- int lastIndex = type.lastIndexOf('.');
- String lastPartB = lastIndex == -1 ? type : type.substring(lastIndex + 1);
- if (!lastPartA.equals(lastPartB)) return false;
- String typeName = toQualifiedName(typeRef.getTypeName());
-
- TypeResolver resolver = new TypeResolver(node.getImportList());
+ 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;
+ 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);
+ TypeResolver resolver = node.getImportListAsTypeResolver();
return resolver.typeMatches(node, type, typeName);
}
@@ -1786,27 +1787,39 @@ public class EclipseHandlerUtil {
if (isPrimitive(variable.type)) return null;
AllocationExpression exception = new AllocationExpression();
setGeneratedBy(exception, source);
- int partCount = 1;
+
+ SingleNameReference varName = new SingleNameReference(variable.name, p);
+ setGeneratedBy(varName, source);
+ NullLiteral nullLiteral = new NullLiteral(pS, pE);
+ setGeneratedBy(nullLiteral, source);
+
+ int equalOperator = exceptionType == NullCheckExceptionType.ASSERTION ? OperatorIds.NOT_EQUAL : OperatorIds.EQUAL_EQUAL;
+ EqualExpression equalExpression = new EqualExpression(varName, nullLiteral, equalOperator);
+ equalExpression.sourceStart = pS; equalExpression.statementEnd = equalExpression.sourceEnd = pE;
+ setGeneratedBy(equalExpression, source);
+
+ StringLiteral message = new StringLiteral(exceptionType.toExceptionMessage(new String(variable.name)).toCharArray(), pS, pE, 0);
+ setGeneratedBy(message, source);
+
+ if (exceptionType == NullCheckExceptionType.ASSERTION) {
+ Statement assertStatement = new AssertStatement(message, equalExpression, pS);
+ setGeneratedBy(assertStatement, source);
+ return assertStatement;
+ }
+
String exceptionTypeStr = exceptionType.getExceptionType();
+ int partCount = 1;
for (int i = 0; i < exceptionTypeStr.length(); i++) if (exceptionTypeStr.charAt(i) == '.') partCount++;
long[] ps = new long[partCount];
Arrays.fill(ps, 0L);
exception.type = new QualifiedTypeReference(fromQualifiedName(exceptionTypeStr), ps);
setGeneratedBy(exception.type, source);
- exception.arguments = new Expression[] {
- new StringLiteral(exceptionType.toExceptionMessage(new String(variable.name)).toCharArray(), pS, pE, 0)
- };
- setGeneratedBy(exception.arguments[0], source);
+ exception.arguments = new Expression[] {message};
+
ThrowStatement throwStatement = new ThrowStatement(exception, pS, pE);
setGeneratedBy(throwStatement, source);
- SingleNameReference varName = new SingleNameReference(variable.name, p);
- setGeneratedBy(varName, source);
- NullLiteral nullLiteral = new NullLiteral(pS, pE);
- setGeneratedBy(nullLiteral, source);
- EqualExpression equalExpression = new EqualExpression(varName, nullLiteral, OperatorIds.EQUAL_EQUAL);
- equalExpression.sourceStart = pS; equalExpression.statementEnd = equalExpression.sourceEnd = pE;
- setGeneratedBy(equalExpression, source);
+
Block throwBlock = new Block(0);
throwBlock.statements = new Statement[] {throwStatement};
throwBlock.sourceStart = pS; throwBlock.sourceEnd = pE;
diff --git a/src/core/lombok/eclipse/handlers/HandleBuilder.java b/src/core/lombok/eclipse/handlers/HandleBuilder.java
index 3391b99d..7a831f3d 100755
--- a/src/core/lombok/eclipse/handlers/HandleBuilder.java
+++ b/src/core/lombok/eclipse/handlers/HandleBuilder.java
@@ -170,10 +170,18 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
List<char[]> typeArgsForToBuilder = null;
if (builderMethodName == null) builderMethodName = "builder";
- if (buildMethodName == null) builderMethodName = "build";
+ if (buildMethodName == null) buildMethodName = "build";
if (builderClassName == null) builderClassName = "";
- if (!checkName("builderMethodName", builderMethodName, annotationNode)) return;
+ boolean generateBuilderMethod;
+ if (builderMethodName.isEmpty()) {
+ generateBuilderMethod = false;
+ } else if (!checkName("builderMethodName", builderMethodName, annotationNode)) {
+ return;
+ } else {
+ generateBuilderMethod = true;
+ }
+
if (!checkName("buildMethodName", buildMethodName, annotationNode)) return;
if (!builderClassName.isEmpty()) {
if (!checkName("builderClassName", builderClassName, annotationNode)) return;
@@ -192,6 +200,8 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
boolean addCleaning = false;
boolean isStatic = true;
+ List<EclipseNode> nonFinalNonDefaultedFields = null;
+
if (parent.get() instanceof TypeDeclaration) {
tdParent = parent;
TypeDeclaration td = (TypeDeclaration) tdParent.get();
@@ -225,7 +235,8 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
if (fd.initialization != null && isDefault == null) {
if (isFinal) continue;
- fieldNode.addWarning("@Builder will ignore the initializing expression entirely. If you want the initializing expression to serve as default, add @Builder.Default. If it is not supposed to be settable during building, make the field final.");
+ if (nonFinalNonDefaultedFields == null) nonFinalNonDefaultedFields = new ArrayList<EclipseNode>();
+ nonFinalNonDefaultedFields.add(fieldNode);
}
if (isDefault != null) {
@@ -486,7 +497,8 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
if (cleanMethod != null) injectMethod(builderType, cleanMethod);
}
- if (methodExists(builderMethodName, tdParent, -1) == MemberExistsResult.NOT_EXISTS) {
+ if (generateBuilderMethod && methodExists(builderMethodName, tdParent, -1) != MemberExistsResult.NOT_EXISTS) generateBuilderMethod = false;
+ if (generateBuilderMethod) {
MethodDeclaration md = generateBuilderMethod(isStatic, builderMethodName, builderClassName, tdParent, typeParams, ast);
if (md != null) injectMethod(tdParent, md);
}
@@ -508,6 +520,12 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
if (md != null) injectMethod(tdParent, md);
}
+
+ if (nonFinalNonDefaultedFields != null && generateBuilderMethod) {
+ for (EclipseNode fieldNode : nonFinalNonDefaultedFields) {
+ fieldNode.addWarning("@Builder will ignore the initializing expression entirely. If you want the initializing expression to serve as default, add @Builder.Default. If it is not supposed to be settable during building, make the field final.");
+ }
+ }
}
private static final char[] BUILDER_TEMP_VAR = {'b', 'u', 'i', 'l', 'd', 'e', 'r'};
diff --git a/src/core/lombok/eclipse/handlers/HandleNonNull.java b/src/core/lombok/eclipse/handlers/HandleNonNull.java
index 1672618d..77c77e1e 100644
--- a/src/core/lombok/eclipse/handlers/HandleNonNull.java
+++ b/src/core/lombok/eclipse/handlers/HandleNonNull.java
@@ -21,27 +21,18 @@
*/
package lombok.eclipse.handlers;
-import static lombok.core.handlers.HandlerUtil.*;
+import static lombok.core.handlers.HandlerUtil.handleFlagUsage;
import static lombok.eclipse.Eclipse.isPrimitive;
import static lombok.eclipse.handlers.EclipseHandlerUtil.*;
import java.util.Arrays;
-import lombok.ConfigurationKeys;
-import lombok.NonNull;
-import lombok.core.AST.Kind;
-import lombok.core.AnnotationValues;
-import lombok.core.HandlerPriority;
-import lombok.eclipse.DeferUntilPostDiet;
-import lombok.eclipse.EclipseAST;
-import lombok.eclipse.EclipseAnnotationHandler;
-import lombok.eclipse.EclipseNode;
-
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration;
import org.eclipse.jdt.internal.compiler.ast.Annotation;
import org.eclipse.jdt.internal.compiler.ast.Argument;
+import org.eclipse.jdt.internal.compiler.ast.AssertStatement;
import org.eclipse.jdt.internal.compiler.ast.Block;
import org.eclipse.jdt.internal.compiler.ast.EqualExpression;
import org.eclipse.jdt.internal.compiler.ast.Expression;
@@ -56,6 +47,16 @@ import org.eclipse.jdt.internal.compiler.ast.TryStatement;
import org.eclipse.jdt.internal.compiler.ast.TypeReference;
import org.mangosdk.spi.ProviderFor;
+import lombok.ConfigurationKeys;
+import lombok.NonNull;
+import lombok.core.AST.Kind;
+import lombok.core.AnnotationValues;
+import lombok.core.HandlerPriority;
+import lombok.eclipse.DeferUntilPostDiet;
+import lombok.eclipse.EclipseAST;
+import lombok.eclipse.EclipseAnnotationHandler;
+import lombok.eclipse.EclipseNode;
+
@DeferUntilPostDiet
@ProviderFor(EclipseAnnotationHandler.class)
@HandlerPriority(value = 512) // 2^9; onParameter=@__(@NonNull) has to run first.
@@ -191,9 +192,11 @@ public class HandleNonNull extends EclipseAnnotationHandler<NonNull> {
}
public char[] returnVarNameIfNullCheck(Statement stat) {
- if (!(stat instanceof IfStatement)) return null;
+ boolean isIf = stat instanceof IfStatement;
+ if (!isIf && !(stat instanceof AssertStatement)) return null;
- /* Check that the if's statement is a throw statement, possibly in a block. */ {
+ if (isIf) {
+ /* Check that the if's statement is a throw statement, possibly in a block. */
Statement then = ((IfStatement) stat).thenStatement;
if (then instanceof Block) {
Statement[] blockStatements = ((Block) then).statements;
@@ -206,11 +209,15 @@ public class HandleNonNull extends EclipseAnnotationHandler<NonNull> {
/* Check that the if's conditional is like 'x == null'. Return from this method (don't generate
a nullcheck) if 'x' is equal to our own variable's name: There's already a nullcheck here. */ {
- Expression cond = ((IfStatement) stat).condition;
+ 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);
- if (operatorId != OperatorIds.EQUAL_EQUAL) return null;
+ if (isIf) {
+ if (operatorId != OperatorIds.EQUAL_EQUAL) return null;
+ } else {
+ if (operatorId != OperatorIds.NOT_EQUAL) return null;
+ }
if (!(bin.left instanceof SingleNameReference)) return null;
if (!(bin.right instanceof NullLiteral)) return null;
return ((SingleNameReference) bin.left).token;
diff --git a/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java b/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java
index 7b6a3c28..6f34eb30 100755
--- a/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java
+++ b/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java
@@ -129,7 +129,14 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
if (builderMethodName == null) builderMethodName = "builder";
if (buildMethodName == null) buildMethodName = "build";
- if (!checkName("builderMethodName", builderMethodName, annotationNode)) return;
+ boolean generateBuilderMethod;
+ if (builderMethodName.isEmpty()) {
+ generateBuilderMethod = false;
+ } else if (!checkName("builderMethodName", builderMethodName, annotationNode)) {
+ return;
+ } else {
+ generateBuilderMethod = true;
+ }
if (!checkName("buildMethodName", buildMethodName, annotationNode)) return;
boolean toBuilder = superbuilderAnnotation.toBuilder();
@@ -150,6 +157,8 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
// Gather all fields of the class that should be set by the builder.
List<EclipseNode> allFields = new ArrayList<EclipseNode>();
+ List<EclipseNode> nonFinalNonDefaultedFields = null;
+
boolean valuePresent = (hasAnnotation(lombok.Value.class, tdParent) || hasAnnotation("lombok.experimental.Value", tdParent));
for (EclipseNode fieldNode : HandleConstructor.findAllFields(tdParent, true)) {
FieldDeclaration fd = (FieldDeclaration) fieldNode.get();
@@ -177,10 +186,9 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
}
if (fd.initialization != null && isDefault == null) {
- if (isFinal) {
- continue;
- }
- fieldNode.addWarning("@Builder will ignore the initializing expression entirely. If you want the initializing expression to serve as default, add @Builder.Default. If it is not supposed to be settable during building, make the field final.");
+ if (isFinal) continue;
+ if (nonFinalNonDefaultedFields == null) nonFinalNonDefaultedFields = new ArrayList<EclipseNode>();
+ nonFinalNonDefaultedFields.add(fieldNode);
}
if (isDefault != null) {
@@ -386,10 +394,17 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
}
// Add the builder() method to the annotated class.
- if (methodExists(builderMethodName, tdParent, -1) == MemberExistsResult.NOT_EXISTS) {
+ if (generateBuilderMethod && methodExists(builderMethodName, tdParent, -1) != MemberExistsResult.NOT_EXISTS) generateBuilderMethod = false;
+ if (generateBuilderMethod) {
MethodDeclaration md = generateBuilderMethod(builderMethodName, builderClassName, builderImplClassName, tdParent, typeParams, ast);
if (md != null) injectMethod(tdParent, md);
}
+
+ if (nonFinalNonDefaultedFields != null && generateBuilderMethod) {
+ for (EclipseNode fieldNode : nonFinalNonDefaultedFields) {
+ fieldNode.addWarning("@SuperBuilder will ignore the initializing expression entirely. If you want the initializing expression to serve as default, add @Builder.Default. If it is not supposed to be settable during building, make the field final.");
+ }
+ }
}
private EclipseNode generateBuilderAbstractClass(EclipseNode tdParent, String builderClass,
diff --git a/src/core/lombok/experimental/FieldNameConstants.java b/src/core/lombok/experimental/FieldNameConstants.java
index d6886890..da97a721 100644
--- a/src/core/lombok/experimental/FieldNameConstants.java
+++ b/src/core/lombok/experimental/FieldNameConstants.java
@@ -41,6 +41,8 @@ public @interface FieldNameConstants {
/**
* Only include fields and methods explicitly marked with {@code @FieldNameConstants.Include}.
* Normally, all (non-static) fields are included by default.
+ *
+ * @return If {@code true}, don't include non-static fields automatically (default: {@code false}).
*/
boolean onlyExplicitlyIncluded() default false;
diff --git a/src/core/lombok/experimental/SuperBuilder.java b/src/core/lombok/experimental/SuperBuilder.java
index be6ea304..aef76a46 100644
--- a/src/core/lombok/experimental/SuperBuilder.java
+++ b/src/core/lombok/experimental/SuperBuilder.java
@@ -49,7 +49,7 @@ import lombok.Singular;
@Target(TYPE)
@Retention(SOURCE)
public @interface SuperBuilder {
- /** @return Name of the method that creates a new builder instance. Default: {@code builder}. */
+ /** @return Name of the method that creates a new builder instance. Default: {@code builder}. If the empty string, suppress generating the {@code builder} method. */
String builderMethodName() default "builder";
/** @return Name of the method in the builder class that creates an instance of your {@code @Builder}-annotated class. */
diff --git a/src/core/lombok/javac/handlers/HandleBuilder.java b/src/core/lombok/javac/handlers/HandleBuilder.java
index 609adbd6..d6fb9728 100644
--- a/src/core/lombok/javac/handlers/HandleBuilder.java
+++ b/src/core/lombok/javac/handlers/HandleBuilder.java
@@ -119,7 +119,15 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
if (buildMethodName == null) buildMethodName = "build";
if (builderClassName == null) builderClassName = "";
- if (!checkName("builderMethodName", builderMethodName, annotationNode)) return;
+ boolean generateBuilderMethod;
+ if (builderMethodName.isEmpty()) {
+ generateBuilderMethod = false;
+ } else if (!checkName("builderMethodName", builderMethodName, annotationNode)) {
+ return;
+ } else {
+ generateBuilderMethod = true;
+ }
+
if (!checkName("buildMethodName", buildMethodName, annotationNode)) return;
if (!builderClassName.isEmpty()) {
if (!checkName("builderClassName", builderClassName, annotationNode)) return;
@@ -140,6 +148,8 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
boolean addCleaning = false;
boolean isStatic = true;
+ ArrayList<JavacNode> nonFinalNonDefaultedFields = null;
+
if (parent.get() instanceof JCClassDecl) {
tdParent = parent;
JCClassDecl td = (JCClassDecl) tdParent.get();
@@ -172,7 +182,8 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
if (fd.init != null && isDefault == null) {
if (isFinal) continue;
- fieldNode.addWarning("@Builder will ignore the initializing expression entirely. If you want the initializing expression to serve as default, add @Builder.Default. If it is not supposed to be settable during building, make the field final.");
+ if (nonFinalNonDefaultedFields == null) nonFinalNonDefaultedFields = new ArrayList<JavacNode>();
+ nonFinalNonDefaultedFields.add(fieldNode);
}
if (isDefault != null) {
@@ -406,7 +417,7 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
}
{
- MemberExistsResult methodExists = methodExists(builderMethodName, builderType, -1);
+ MemberExistsResult methodExists = methodExists(buildMethodName, builderType, -1);
if (methodExists == MemberExistsResult.EXISTS_BY_LOMBOK) methodExists = methodExists(buildMethodName, builderType, 0);
if (methodExists == MemberExistsResult.NOT_EXISTS) {
JCMethodDecl md = generateBuildMethod(tdParent, isStatic, buildMethodName, nameOfBuilderMethod, returnType, builderFields, builderType, thrownExceptions, ast, addCleaning);
@@ -431,7 +442,8 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
if (addCleaning) injectMethod(builderType, generateCleanMethod(builderFields, builderType, ast));
- if (methodExists(builderMethodName, tdParent, -1) == MemberExistsResult.NOT_EXISTS) {
+ if (generateBuilderMethod && methodExists(builderMethodName, tdParent, -1) != MemberExistsResult.NOT_EXISTS) generateBuilderMethod = false;
+ if (generateBuilderMethod) {
JCMethodDecl md = generateBuilderMethod(isStatic, builderMethodName, builderClassName, annotationNode, tdParent, typeParams);
recursiveSetGeneratedBy(md, ast, annotationNode.getContext());
if (md != null) injectMethod(tdParent, md);
@@ -459,6 +471,12 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
}
}
}
+
+ if (nonFinalNonDefaultedFields != null && generateBuilderMethod) {
+ for (JavacNode fieldNode : nonFinalNonDefaultedFields) {
+ fieldNode.addWarning("@Builder will ignore the initializing expression entirely. If you want the initializing expression to serve as default, add @Builder.Default. If it is not supposed to be settable during building, make the field final.");
+ }
+ }
}
private static String unpack(JCExpression expr) {
diff --git a/src/core/lombok/javac/handlers/HandleNonNull.java b/src/core/lombok/javac/handlers/HandleNonNull.java
index 9a81ffff..49b987ce 100644
--- a/src/core/lombok/javac/handlers/HandleNonNull.java
+++ b/src/core/lombok/javac/handlers/HandleNonNull.java
@@ -21,13 +21,16 @@
*/
package lombok.javac.handlers;
-import static lombok.core.handlers.HandlerUtil.*;
+import static lombok.core.handlers.HandlerUtil.handleFlagUsage;
import static lombok.javac.Javac.*;
+import static lombok.javac.JavacTreeMaker.TreeTag.treeTag;
+import static lombok.javac.JavacTreeMaker.TypeTag.typeTag;
import static lombok.javac.handlers.JavacHandlerUtil.*;
import org.mangosdk.spi.ProviderFor;
import com.sun.tools.javac.tree.JCTree.JCAnnotation;
+import com.sun.tools.javac.tree.JCTree.JCAssert;
import com.sun.tools.javac.tree.JCTree.JCBinary;
import com.sun.tools.javac.tree.JCTree.JCBlock;
import com.sun.tools.javac.tree.JCTree.JCExpression;
@@ -45,13 +48,11 @@ import com.sun.tools.javac.util.List;
import lombok.ConfigurationKeys;
import lombok.NonNull;
+import lombok.core.AST.Kind;
import lombok.core.AnnotationValues;
import lombok.core.HandlerPriority;
-import lombok.core.AST.Kind;
import lombok.javac.JavacAnnotationHandler;
import lombok.javac.JavacNode;
-import static lombok.javac.JavacTreeMaker.TypeTag.*;
-import static lombok.javac.JavacTreeMaker.TreeTag.*;
@ProviderFor(JavacAnnotationHandler.class)
@HandlerPriority(value = 512) // 2^9; onParameter=@__(@NonNull) has to run first.
@@ -161,14 +162,16 @@ public class HandleNonNull extends JavacAnnotationHandler<NonNull> {
}
/**
- * Checks if the statement is of the form 'if (x == null) {throw WHATEVER;},
+ * Checks if the statement is of the form 'if (x == null) {throw WHATEVER;}' or 'assert x != null;',
* where the block braces are optional. If it is of this form, returns "x".
* If it is not of this form, returns null.
*/
public String returnVarNameIfNullCheck(JCStatement stat) {
- if (!(stat instanceof JCIf)) return null;
+ boolean isIf = stat instanceof JCIf;
+ if (!isIf && !(stat instanceof JCAssert)) return null;
- /* Check that the if's statement is a throw statement, possibly in a block. */ {
+ if (isIf) {
+ /* Check that the if's statement is a throw statement, possibly in a block. */
JCStatement then = ((JCIf) stat).thenpart;
if (then instanceof JCBlock) {
List<JCStatement> stats = ((JCBlock) then).stats;
@@ -180,11 +183,15 @@ public class HandleNonNull extends JavacAnnotationHandler<NonNull> {
/* Check that the if's conditional is like 'x == null'. Return from this method (don't generate
a nullcheck) if 'x' is equal to our own variable's name: There's already a nullcheck here. */ {
- JCExpression cond = ((JCIf) stat).cond;
+ JCExpression cond = isIf ? ((JCIf) stat).cond : ((JCAssert) stat).cond;
while (cond instanceof JCParens) cond = ((JCParens) cond).expr;
if (!(cond instanceof JCBinary)) return null;
JCBinary bin = (JCBinary) cond;
- if (!CTC_EQUAL.equals(treeTag(bin))) return null;
+ if (isIf) {
+ if (!CTC_EQUAL.equals(treeTag(bin))) return null;
+ } else {
+ if (!CTC_NOT_EQUAL.equals(treeTag(bin))) return null;
+ }
if (!(bin.lhs instanceof JCIdent)) return null;
if (!(bin.rhs instanceof JCLiteral)) return null;
if (!CTC_BOT.equals(typeTag(bin.rhs))) return null;
diff --git a/src/core/lombok/javac/handlers/HandleSuperBuilder.java b/src/core/lombok/javac/handlers/HandleSuperBuilder.java
index 7ef6b658..7eb9873b 100644
--- a/src/core/lombok/javac/handlers/HandleSuperBuilder.java
+++ b/src/core/lombok/javac/handlers/HandleSuperBuilder.java
@@ -103,7 +103,14 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
if (builderMethodName == null) builderMethodName = "builder";
if (buildMethodName == null) buildMethodName = "build";
- if (!checkName("builderMethodName", builderMethodName, annotationNode)) return;
+ boolean generateBuilderMethod;
+ if (builderMethodName.isEmpty()) {
+ generateBuilderMethod = false;
+ } else if (!checkName("builderMethodName", builderMethodName, annotationNode)) {
+ return;
+ } else {
+ generateBuilderMethod = true;
+ }
if (!checkName("buildMethodName", buildMethodName, annotationNode)) return;
boolean toBuilder = superbuilderAnnotation.toBuilder();
@@ -125,6 +132,8 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
// Gather all fields of the class that should be set by the builder.
JCClassDecl td = (JCClassDecl) tdParent.get();
ListBuffer<JavacNode> allFields = new ListBuffer<JavacNode>();
+ ArrayList<JavacNode> nonFinalNonDefaultedFields = null;
+
boolean valuePresent = (hasAnnotation(lombok.Value.class, tdParent) || hasAnnotation("lombok.experimental.Value", tdParent));
for (JavacNode fieldNode : HandleConstructor.findAllFields(tdParent, true)) {
JCVariableDecl fd = (JCVariableDecl) fieldNode.get();
@@ -150,7 +159,8 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
if (fd.init != null && isDefault == null) {
if (isFinal) continue;
- fieldNode.addWarning("@SuperBuilder will ignore the initializing expression entirely. If you want the initializing expression to serve as default, add @Builder.Default. If it is not supposed to be settable during building, make the field final.");
+ if (nonFinalNonDefaultedFields == null) nonFinalNonDefaultedFields = new ArrayList<JavacNode>();
+ nonFinalNonDefaultedFields.add(fieldNode);
}
if (isDefault != null) {
@@ -347,7 +357,8 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
// Add the builder() method to the annotated class.
// Allow users to specify their own builder() methods, e.g., to provide default values.
- if (methodExists(builderMethodName, tdParent, -1) == MemberExistsResult.NOT_EXISTS) {
+ if (generateBuilderMethod && methodExists(builderMethodName, tdParent, -1) != MemberExistsResult.NOT_EXISTS) generateBuilderMethod = false;
+ if (generateBuilderMethod) {
JCMethodDecl builderMethod = generateBuilderMethod(builderMethodName, builderClassName, builderImplClassName, annotationNode, tdParent, typeParams);
recursiveSetGeneratedBy(builderMethod, ast, annotationNode.getContext());
if (builderMethod != null) injectMethod(tdParent, builderMethod);
@@ -369,6 +380,12 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
// Should not happen.
}
}
+
+ if (nonFinalNonDefaultedFields != null && generateBuilderMethod) {
+ for (JavacNode fieldNode : nonFinalNonDefaultedFields) {
+ fieldNode.addWarning("@SuperBuilder will ignore the initializing expression entirely. If you want the initializing expression to serve as default, add @Builder.Default. If it is not supposed to be settable during building, make the field final.");
+ }
+ }
}
/**
diff --git a/src/core/lombok/javac/handlers/JavacHandlerUtil.java b/src/core/lombok/javac/handlers/JavacHandlerUtil.java
index f08098d2..509a7397 100644
--- a/src/core/lombok/javac/handlers/JavacHandlerUtil.java
+++ b/src/core/lombok/javac/handlers/JavacHandlerUtil.java
@@ -40,36 +40,15 @@ import java.util.regex.Pattern;
import javax.lang.model.element.Element;
-import lombok.AccessLevel;
-import lombok.ConfigurationKeys;
-import lombok.Data;
-import lombok.Getter;
-import lombok.core.AST.Kind;
-import lombok.core.AnnotationValues;
-import lombok.core.LombokImmutableList;
-import lombok.core.AnnotationValues.AnnotationValue;
-import lombok.core.CleanupTask;
-import lombok.core.TypeResolver;
-import lombok.core.configuration.NullCheckExceptionType;
-import lombok.core.configuration.TypeName;
-import lombok.core.handlers.HandlerUtil;
-import lombok.delombok.LombokOptionsFactory;
-import lombok.experimental.Accessors;
-import lombok.experimental.Tolerate;
-import lombok.javac.Javac;
-import lombok.javac.JavacNode;
-import lombok.javac.JavacTreeMaker;
-import lombok.permit.Permit;
-
import com.sun.tools.javac.code.BoundKind;
import com.sun.tools.javac.code.Flags;
import com.sun.tools.javac.code.Scope;
import com.sun.tools.javac.code.Symbol;
-import com.sun.tools.javac.code.Symtab;
-import com.sun.tools.javac.code.Type;
import com.sun.tools.javac.code.Symbol.ClassSymbol;
import com.sun.tools.javac.code.Symbol.MethodSymbol;
import com.sun.tools.javac.code.Symbol.VarSymbol;
+import com.sun.tools.javac.code.Symtab;
+import com.sun.tools.javac.code.Type;
import com.sun.tools.javac.code.Type.MethodType;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.JCTree.JCAnnotation;
@@ -83,6 +62,7 @@ import com.sun.tools.javac.tree.JCTree.JCExpressionStatement;
import com.sun.tools.javac.tree.JCTree.JCFieldAccess;
import com.sun.tools.javac.tree.JCTree.JCIdent;
import com.sun.tools.javac.tree.JCTree.JCImport;
+import com.sun.tools.javac.tree.JCTree.JCLiteral;
import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
import com.sun.tools.javac.tree.JCTree.JCMethodInvocation;
import com.sun.tools.javac.tree.JCTree.JCModifiers;
@@ -103,6 +83,28 @@ import com.sun.tools.javac.util.ListBuffer;
import com.sun.tools.javac.util.Name;
import com.sun.tools.javac.util.Options;
+import lombok.AccessLevel;
+import lombok.ConfigurationKeys;
+import lombok.Data;
+import lombok.Getter;
+import lombok.core.AST.Kind;
+import lombok.core.AnnotationValues;
+import lombok.core.AnnotationValues.AnnotationValue;
+import lombok.core.CleanupTask;
+import lombok.core.LombokImmutableList;
+import lombok.core.TypeResolver;
+import lombok.core.configuration.NullCheckExceptionType;
+import lombok.core.configuration.TypeName;
+import lombok.core.handlers.HandlerUtil;
+import lombok.core.handlers.HandlerUtil.FieldAccess;
+import lombok.delombok.LombokOptionsFactory;
+import lombok.experimental.Accessors;
+import lombok.experimental.Tolerate;
+import lombok.javac.Javac;
+import lombok.javac.JavacNode;
+import lombok.javac.JavacTreeMaker;
+import lombok.permit.Permit;
+
/**
* Container for static utility methods useful to handlers written for javac.
*/
@@ -265,7 +267,7 @@ public class JavacHandlerUtil {
*/
public static boolean annotationTypeMatches(Class<? extends Annotation> type, JavacNode node) {
if (node.getKind() != Kind.ANNOTATION) return false;
- return typeMatches(type, node, ((JCAnnotation)node.get()).annotationType);
+ return typeMatches(type, node, ((JCAnnotation) node.get()).annotationType);
}
/**
@@ -298,9 +300,14 @@ public class JavacHandlerUtil {
* @param typeNode A type reference to check.
*/
public static boolean typeMatches(String type, JavacNode node, JCTree typeNode) {
- String typeName = typeNode.toString();
-
- TypeResolver resolver = new TypeResolver(node.getImportList());
+ String typeName = typeNode == null ? null : typeNode.toString();
+ if (typeName == null || typeName.length() == 0) return false;
+ int lastIndexA = typeName.lastIndexOf('.') + 1;
+ int lastIndexB = Math.max(type.lastIndexOf('.'), type.lastIndexOf('$')) + 1;
+ int len = typeName.length() - lastIndexA;
+ if (len != type.length() - lastIndexB) return false;
+ for (int i = 0; i < len; i++) if (typeName.charAt(i + lastIndexA) != type.charAt(i + lastIndexB)) return false;
+ TypeResolver resolver = node.getImportListAsTypeResolver();
return resolver.typeMatches(node, type, typeName);
}
@@ -1479,8 +1486,14 @@ public class JavacHandlerUtil {
if (isPrimitive(varDecl.vartype)) return null;
Name fieldName = varDecl.name;
+
+ JCLiteral message = maker.Literal(exceptionType.toExceptionMessage(fieldName.toString()));
+ if (exceptionType == NullCheckExceptionType.ASSERTION) {
+ return maker.Assert(maker.Binary(CTC_NOT_EQUAL, maker.Ident(fieldName), maker.Literal(CTC_BOT, null)), message);
+ }
+
JCExpression exType = genTypeRef(variable, exceptionType.getExceptionType());
- JCExpression exception = maker.NewClass(null, List.<JCExpression>nil(), exType, List.<JCExpression>of(maker.Literal(exceptionType.toExceptionMessage(fieldName.toString()))), null);
+ JCExpression exception = maker.NewClass(null, List.<JCExpression>nil(), exType, List.<JCExpression>of(message), null);
JCStatement throwStatement = maker.Throw(exception);
JCBlock throwBlock = maker.Block(0, List.of(throwStatement));
return maker.If(maker.Binary(CTC_EQUAL, maker.Ident(fieldName), maker.Literal(CTC_BOT, null)), throwBlock, null);
diff --git a/src/delombok/lombok/delombok/Delombok.java b/src/delombok/lombok/delombok/Delombok.java
index 9582c3b8..8f4f99e5 100755
--- a/src/delombok/lombok/delombok/Delombok.java
+++ b/src/delombok/lombok/delombok/Delombok.java
@@ -753,6 +753,7 @@ public class Delombok {
Object care = callAttributeMethodOnJavaCompiler(delegate, delegate.todo);
callFlowMethodOnJavaCompiler(delegate, care);
+
FormatPreferences fps = new FormatPreferences(formatPrefs);
for (JCCompilationUnit unit : roots) {
DelombokResult result = new DelombokResult(catcher.getComments(unit), unit, force || options.isChanged(unit), fps);
diff --git a/src/delombok/lombok/delombok/PrettyPrinter.java b/src/delombok/lombok/delombok/PrettyPrinter.java
index 353bd753..832dbe0a 100644
--- a/src/delombok/lombok/delombok/PrettyPrinter.java
+++ b/src/delombok/lombok/delombok/PrettyPrinter.java
@@ -648,7 +648,11 @@ public class PrettyPrinter extends JCTree.Visitor {
*/
try {
innermostArrayBracketsAreVarargs = varargs;
- print(tree.vartype);
+ if (tree.vartype == null || tree.vartype.pos == -1) {
+ print("var");
+ } else {
+ print(tree.vartype);
+ }
} finally {
innermostArrayBracketsAreVarargs = false;
}