aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/lombok/core/configuration/NullCheckExceptionType.java38
-rw-r--r--src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java79
-rw-r--r--src/core/lombok/eclipse/handlers/HandleNonNull.java22
-rw-r--r--src/core/lombok/javac/handlers/HandleNonNull.java32
-rw-r--r--src/core/lombok/javac/handlers/JavacHandlerUtil.java6
5 files changed, 143 insertions, 34 deletions
diff --git a/src/core/lombok/core/configuration/NullCheckExceptionType.java b/src/core/lombok/core/configuration/NullCheckExceptionType.java
index d226c0a8..3c9e325d 100644
--- a/src/core/lombok/core/configuration/NullCheckExceptionType.java
+++ b/src/core/lombok/core/configuration/NullCheckExceptionType.java
@@ -21,28 +21,64 @@
*/
package lombok.core.configuration;
+import lombok.core.LombokImmutableList;
-@ExampleValueString("[NullPointerException | IllegalArgumentException | Assertion]")
+@ExampleValueString("[NullPointerException | IllegalArgumentException | Assertion | JDK | GUAVA]")
public enum NullCheckExceptionType {
ILLEGAL_ARGUMENT_EXCEPTION {
@Override public String getExceptionType() {
return "java.lang.IllegalArgumentException";
}
+
+ @Override public LombokImmutableList<String> getMethod() {
+ return null;
+ }
},
NULL_POINTER_EXCEPTION {
@Override public String getExceptionType() {
return "java.lang.NullPointerException";
}
+
+ @Override public LombokImmutableList<String> getMethod() {
+ return null;
+ }
},
ASSERTION {
@Override public String getExceptionType() {
return null;
}
+
+ @Override public LombokImmutableList<String> getMethod() {
+ return null;
+ }
+ },
+ JDK {
+ @Override public String getExceptionType() {
+ return null;
+ }
+
+ @Override public LombokImmutableList<String> getMethod() {
+ return METHOD_JDK;
+ }
+ },
+ GUAVA {
+ @Override public String getExceptionType() {
+ return null;
+ }
+
+ @Override public LombokImmutableList<String> getMethod() {
+ return METHOD_GUAVA;
+ }
};
+ private static final LombokImmutableList<String> METHOD_JDK = LombokImmutableList.of("java", "util", "Objects", "requireNonNull");
+ private static final LombokImmutableList<String> METHOD_GUAVA = LombokImmutableList.of("com", "google", "common", "base", "Preconditions", "checkNotNull");
+
public String toExceptionMessage(String fieldName) {
return fieldName + " is marked non-null but is null";
}
public abstract String getExceptionType();
+
+ public abstract LombokImmutableList<String> getMethod();
}
diff --git a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java
index 37976ae3..11a2b9bd 100644
--- a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java
+++ b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java
@@ -38,26 +38,6 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import lombok.AccessLevel;
-import lombok.ConfigurationKeys;
-import lombok.Data;
-import lombok.Getter;
-import lombok.Lombok;
-import lombok.core.AST.Kind;
-import lombok.core.AnnotationValues;
-import lombok.core.AnnotationValues.AnnotationValue;
-import lombok.core.TypeResolver;
-import lombok.core.configuration.NullCheckExceptionType;
-import lombok.core.configuration.TypeName;
-import lombok.core.debug.ProblemReporter;
-import lombok.core.handlers.HandlerUtil;
-import lombok.eclipse.Eclipse;
-import lombok.eclipse.EclipseAST;
-import lombok.eclipse.EclipseNode;
-import lombok.experimental.Accessors;
-import lombok.experimental.Tolerate;
-import lombok.permit.Permit;
-
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration;
@@ -121,6 +101,28 @@ import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
import org.eclipse.jdt.internal.compiler.lookup.WildcardBinding;
+import lombok.AccessLevel;
+import lombok.ConfigurationKeys;
+import lombok.Data;
+import lombok.Getter;
+import lombok.Lombok;
+import lombok.core.AST.Kind;
+import lombok.core.AnnotationValues;
+import lombok.core.AnnotationValues.AnnotationValue;
+import lombok.core.LombokImmutableList;
+import lombok.core.TypeResolver;
+import lombok.core.configuration.NullCheckExceptionType;
+import lombok.core.configuration.TypeName;
+import lombok.core.debug.ProblemReporter;
+import lombok.core.handlers.HandlerUtil;
+import lombok.core.handlers.HandlerUtil.FieldAccess;
+import lombok.eclipse.Eclipse;
+import lombok.eclipse.EclipseAST;
+import lombok.eclipse.EclipseNode;
+import lombok.experimental.Accessors;
+import lombok.experimental.Tolerate;
+import lombok.permit.Permit;
+
/**
* Container for static utility methods useful to handlers written for eclipse.
*/
@@ -1818,8 +1820,6 @@ public class EclipseHandlerUtil {
/**
* Generates a new statement that checks if the given local variable is null, and if so, throws a specified exception with the
* variable name as message.
- *
- * @param exName The name of the exception to throw; normally {@code java.lang.NullPointerException}.
*/
public static Statement generateNullCheck(TypeReference type, char[] variable, EclipseNode sourceNode) {
NullCheckExceptionType exceptionType = sourceNode.getAst().readConfiguration(ConfigurationKeys.NON_NULL_EXCEPTION_TYPE);
@@ -1828,24 +1828,44 @@ public class EclipseHandlerUtil {
ASTNode source = sourceNode.get();
int pS = source.sourceStart, pE = source.sourceEnd;
- long p = (long)pS << 32 | pE;
+ long p = (long) pS << 32 | pE;
if (isPrimitive(type)) return null;
+ SingleNameReference varName = new SingleNameReference(variable, p);
+ setGeneratedBy(varName, source);
+
+ StringLiteral message = new StringLiteral(exceptionType.toExceptionMessage(new String(variable)).toCharArray(), pS, pE, 0);
+ setGeneratedBy(message, source);
+
+ LombokImmutableList<String> method = exceptionType.getMethod();
+ if (method != null) {
+
+ MessageSend invocation = new MessageSend();
+ invocation.sourceStart = pS; invocation.sourceEnd = pE;
+ setGeneratedBy(invocation, source);
+
+ char[][] utilityTypeName = new char[method.size() - 1][];
+ for (int i = 0; i < method.size() - 1; i++) {
+ utilityTypeName[i] = method.get(i).toCharArray();
+ }
+
+ invocation.receiver = new QualifiedNameReference(utilityTypeName, new long[method.size()], pS, pE);
+ setGeneratedBy(invocation.receiver, source);
+ invocation.selector = method.get(method.size() - 1).toCharArray();
+ invocation.arguments = new Expression[] {varName, message};
+ return invocation;
+ }
+
AllocationExpression exception = new AllocationExpression();
setGeneratedBy(exception, source);
- SingleNameReference varName = new SingleNameReference(variable, 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)).toCharArray(), pS, pE, 0);
- setGeneratedBy(message, source);
if (exceptionType == NullCheckExceptionType.ASSERTION) {
Statement assertStatement = new AssertStatement(message, equalExpression, pS);
@@ -1865,7 +1885,6 @@ public class EclipseHandlerUtil {
ThrowStatement throwStatement = new ThrowStatement(exception, pS, pE);
setGeneratedBy(throwStatement, 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 77c77e1e..c61ce02d 100644
--- a/src/core/lombok/eclipse/handlers/HandleNonNull.java
+++ b/src/core/lombok/eclipse/handlers/HandleNonNull.java
@@ -33,10 +33,12 @@ 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.Assignment;
import org.eclipse.jdt.internal.compiler.ast.Block;
import org.eclipse.jdt.internal.compiler.ast.EqualExpression;
import org.eclipse.jdt.internal.compiler.ast.Expression;
import org.eclipse.jdt.internal.compiler.ast.IfStatement;
+import org.eclipse.jdt.internal.compiler.ast.MessageSend;
import org.eclipse.jdt.internal.compiler.ast.NullLiteral;
import org.eclipse.jdt.internal.compiler.ast.OperatorIds;
import org.eclipse.jdt.internal.compiler.ast.SingleNameReference;
@@ -61,6 +63,9 @@ import lombok.eclipse.EclipseNode;
@ProviderFor(EclipseAnnotationHandler.class)
@HandlerPriority(value = 512) // 2^9; onParameter=@__(@NonNull) has to run first.
public class HandleNonNull extends EclipseAnnotationHandler<NonNull> {
+ private static final char[] REQUIRE_NON_NULL = "requireNonNull".toCharArray();
+ private static final char[] CHECK_NOT_NULL = "checkNotNull".toCharArray();
+
public static final HandleNonNull INSTANCE = new HandleNonNull();
public void fix(EclipseNode method) {
@@ -193,7 +198,22 @@ public class HandleNonNull extends EclipseAnnotationHandler<NonNull> {
public char[] returnVarNameIfNullCheck(Statement stat) {
boolean isIf = stat instanceof IfStatement;
- if (!isIf && !(stat instanceof AssertStatement)) return null;
+ boolean isExpression = stat instanceof Expression;
+ if (!isIf && !(stat instanceof AssertStatement) && !isExpression) return null;
+
+ if (isExpression) {
+ /* Check if the statements contains a call to checkNotNull or requireNonNull */
+ Expression expression = (Expression) stat;
+ if (expression instanceof Assignment) expression = ((Assignment) expression).expression;
+ if (!(expression instanceof MessageSend)) return null;
+
+ MessageSend invocation = (MessageSend) expression;
+ if (!Arrays.equals(invocation.selector, CHECK_NOT_NULL) && !Arrays.equals(invocation.selector, REQUIRE_NON_NULL)) return null;
+ if (invocation.arguments == null || invocation.arguments.length == 0) return null;
+ Expression firstArgument = invocation.arguments[0];
+ if (!(firstArgument instanceof SingleNameReference)) return null;
+ return ((SingleNameReference) firstArgument).token;
+ }
if (isIf) {
/* Check that the if's statement is a throw statement, possibly in a block. */
diff --git a/src/core/lombok/javac/handlers/HandleNonNull.java b/src/core/lombok/javac/handlers/HandleNonNull.java
index 49b987ce..079d5b04 100644
--- a/src/core/lombok/javac/handlers/HandleNonNull.java
+++ b/src/core/lombok/javac/handlers/HandleNonNull.java
@@ -31,13 +31,17 @@ 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.JCAssign;
import com.sun.tools.javac.tree.JCTree.JCBinary;
import com.sun.tools.javac.tree.JCTree.JCBlock;
import com.sun.tools.javac.tree.JCTree.JCExpression;
+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.JCIf;
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.JCParens;
import com.sun.tools.javac.tree.JCTree.JCStatement;
import com.sun.tools.javac.tree.JCTree.JCSynchronized;
@@ -45,6 +49,7 @@ import com.sun.tools.javac.tree.JCTree.JCThrow;
import com.sun.tools.javac.tree.JCTree.JCTry;
import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
import com.sun.tools.javac.util.List;
+import com.sun.tools.javac.util.Name;
import lombok.ConfigurationKeys;
import lombok.NonNull;
@@ -167,8 +172,31 @@ public class HandleNonNull extends JavacAnnotationHandler<NonNull> {
* If it is not of this form, returns null.
*/
public String returnVarNameIfNullCheck(JCStatement stat) {
- boolean isIf = stat instanceof JCIf;
- if (!isIf && !(stat instanceof JCAssert)) return null;
+ boolean isIf = stat instanceof JCIf;
+ boolean isExpression = stat instanceof JCExpressionStatement;
+ if (!isIf && !(stat instanceof JCAssert) && !isExpression) return null;
+
+ if (isExpression) {
+ /* Check if the statements contains a call to checkNotNull or requireNonNull */
+ JCExpression expression = ((JCExpressionStatement) stat).expr;
+ if (expression instanceof JCAssign) expression = ((JCAssign) expression).rhs;
+ if (!(expression instanceof JCMethodInvocation)) return null;
+
+ JCMethodInvocation invocation = (JCMethodInvocation) expression;
+ JCExpression method = invocation.meth;
+ Name name = null;
+ if (method instanceof JCFieldAccess) {
+ name = ((JCFieldAccess) method).name;
+ } else if (method instanceof JCIdent) {
+ name = ((JCIdent) method).name;
+ }
+ if (name == null || (!name.contentEquals("checkNotNull") && !name.contentEquals("requireNonNull"))) return null;
+
+ if (invocation.args.isEmpty()) return null;
+ JCExpression firstArgument = invocation.args.head;
+ if (!(firstArgument instanceof JCIdent)) return null;
+ return ((JCIdent) firstArgument).toString();
+ }
if (isIf) {
/* Check that the if's statement is a throw statement, possibly in a block. */
diff --git a/src/core/lombok/javac/handlers/JavacHandlerUtil.java b/src/core/lombok/javac/handlers/JavacHandlerUtil.java
index 76f3c1ad..5f0f39b0 100644
--- a/src/core/lombok/javac/handlers/JavacHandlerUtil.java
+++ b/src/core/lombok/javac/handlers/JavacHandlerUtil.java
@@ -1529,6 +1529,12 @@ public class JavacHandlerUtil {
if (isPrimitive(typeNode)) return null;
JCLiteral message = maker.Literal(exceptionType.toExceptionMessage(varName.toString()));
+
+ LombokImmutableList<String> method = exceptionType.getMethod();
+ if (method != null) {
+ return maker.Exec(maker.Apply(List.<JCExpression>nil(), chainDots(source, method), List.of(maker.Ident(varName), message)));
+ }
+
if (exceptionType == NullCheckExceptionType.ASSERTION) {
return maker.Assert(maker.Binary(CTC_NOT_EQUAL, maker.Ident(varName), maker.Literal(CTC_BOT, null)), message);
}