aboutsummaryrefslogtreecommitdiff
path: root/src/core/lombok
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/lombok')
-rw-r--r--src/core/lombok/NonNull.java13
-rw-r--r--src/core/lombok/core/configuration/NullCheckExceptionType.java24
-rw-r--r--src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java37
-rw-r--r--src/core/lombok/eclipse/handlers/HandleNonNull.java37
-rw-r--r--src/core/lombok/javac/handlers/HandleNonNull.java25
-rw-r--r--src/core/lombok/javac/handlers/JavacHandlerUtil.java56
6 files changed, 109 insertions, 83 deletions
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/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/eclipse/handlers/EclipseHandlerUtil.java b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java
index 78b11873..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;
@@ -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/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/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/JavacHandlerUtil.java b/src/core/lombok/javac/handlers/JavacHandlerUtil.java
index 9e6c8c00..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.
*/
@@ -1484,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);