aboutsummaryrefslogtreecommitdiff
path: root/src/core/lombok/eclipse
diff options
context:
space:
mode:
authorReinier Zwitserloot <r.zwitserloot@projectlombok.org>2020-01-20 15:25:08 +0100
committerReinier Zwitserloot <r.zwitserloot@projectlombok.org>2020-01-28 16:21:39 +0100
commite95680a76733c22ee5937a586ee50c703d5ba621 (patch)
tree3eaefce07c41760468c3c2a17c86297e2304a730 /src/core/lombok/eclipse
parentfa70b194aa7db62bdbc4cc759a606f97fe50fc92 (diff)
downloadlombok-e95680a76733c22ee5937a586ee50c703d5ba621.tar.gz
lombok-e95680a76733c22ee5937a586ee50c703d5ba621.tar.bz2
lombok-e95680a76733c22ee5937a586ee50c703d5ba621.zip
[issue #2221] [issue #788] Lombok now adds nullity annotations.
Which 'flavour' is defined in lombok.config; applied to toString, equals, canEqual, and plural-form of `@Singular`.
Diffstat (limited to 'src/core/lombok/eclipse')
-rw-r--r--src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java97
-rwxr-xr-xsrc/core/lombok/eclipse/handlers/EclipseSingularsRecipes.java6
-rwxr-xr-xsrc/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java2
-rw-r--r--src/core/lombok/eclipse/handlers/HandleToString.java3
-rw-r--r--src/core/lombok/eclipse/handlers/HandleWith.java4
-rwxr-xr-xsrc/core/lombok/eclipse/handlers/singulars/EclipseGuavaSingularizer.java12
-rwxr-xr-xsrc/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSetSingularizer.java9
-rwxr-xr-xsrc/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilMapSingularizer.java9
8 files changed, 126 insertions, 16 deletions
diff --git a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java
index aa48e000..bd0ad23b 100644
--- a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java
+++ b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java
@@ -43,6 +43,7 @@ import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration;
import org.eclipse.jdt.internal.compiler.ast.AllocationExpression;
import org.eclipse.jdt.internal.compiler.ast.Annotation;
+import org.eclipse.jdt.internal.compiler.ast.Argument;
import org.eclipse.jdt.internal.compiler.ast.ArrayInitializer;
import org.eclipse.jdt.internal.compiler.ast.ArrayQualifiedTypeReference;
import org.eclipse.jdt.internal.compiler.ast.ArrayTypeReference;
@@ -112,6 +113,7 @@ import lombok.core.AnnotationValues.AnnotationValue;
import lombok.core.LombokImmutableList;
import lombok.core.TypeResolver;
import lombok.core.configuration.CheckerFrameworkVersion;
+import lombok.core.configuration.NullAnnotationLibrary;
import lombok.core.configuration.NullCheckExceptionType;
import lombok.core.configuration.TypeName;
import lombok.core.debug.ProblemReporter;
@@ -2381,6 +2383,101 @@ public class EclipseHandlerUtil {
return p.equals("Object") || p.equals("java.lang.Object");
}
+ public static void createRelevantNullableAnnotation(EclipseNode typeNode, MethodDeclaration mth) {
+ NullAnnotationLibrary lib = typeNode.getAst().readConfiguration(ConfigurationKeys.ADD_NULL_ANNOTATIONS);
+ if (lib == null) return;
+
+ applyAnnotationToMethodDecl(typeNode, mth, lib.getNullableAnnotation(), lib.isTypeUse());
+ }
+
+ public static void createRelevantNonNullAnnotation(EclipseNode typeNode, MethodDeclaration mth) {
+ NullAnnotationLibrary lib = typeNode.getAst().readConfiguration(ConfigurationKeys.ADD_NULL_ANNOTATIONS);
+ if (lib == null) return;
+
+ applyAnnotationToMethodDecl(typeNode, mth, lib.getNonNullAnnotation(), lib.isTypeUse());
+ }
+
+ public static void createRelevantNullableAnnotation(EclipseNode typeNode, Argument arg) {
+ NullAnnotationLibrary lib = typeNode.getAst().readConfiguration(ConfigurationKeys.ADD_NULL_ANNOTATIONS);
+ if (lib == null) return;
+
+ applyAnnotationToVarDecl(typeNode, arg, lib.getNullableAnnotation(), lib.isTypeUse());
+ }
+
+ public static void createRelevantNonNullAnnotation(EclipseNode typeNode, Argument arg) {
+ NullAnnotationLibrary lib = typeNode.getAst().readConfiguration(ConfigurationKeys.ADD_NULL_ANNOTATIONS);
+ if (lib == null) return;
+
+ applyAnnotationToVarDecl(typeNode, arg, lib.getNonNullAnnotation(), lib.isTypeUse());
+ }
+
+ private static void applyAnnotationToMethodDecl(EclipseNode typeNode, MethodDeclaration mth, String annType, boolean typeUse) {
+ if (annType == null) return;
+
+ int partCount = 1;
+ for (int i = 0; i < annType.length(); i++) if (annType.charAt(i) == '.') partCount++;
+ long[] ps = new long[partCount];
+ Arrays.fill(ps, 0L);
+ Annotation ann = new MarkerAnnotation(new QualifiedTypeReference(Eclipse.fromQualifiedName(annType), ps), 0);
+
+ if (!typeUse || mth.returnType == null || mth.returnType.getTypeName().length < 2) {
+ Annotation[] a = mth.annotations;
+ if (a == null) a = new Annotation[1];
+ else {
+ Annotation[] b = new Annotation[a.length + 1];
+ System.arraycopy(a, 0, b, 0, a.length);
+ a = b;
+ }
+ a[a.length - 1] = ann;
+ mth.annotations = a;
+ } else {
+ int len = mth.returnType.getTypeName().length;
+ if (mth.returnType.annotations == null) mth.returnType.annotations = new Annotation[len][];
+ Annotation[] a = mth.returnType.annotations[len - 1];
+ if (a == null) a = new Annotation[1];
+ else {
+ Annotation[] b = new Annotation[a.length + 1];
+ System.arraycopy(a, 0, b, 1, a.length);
+ a = b;
+ }
+ a[0] = ann;
+ mth.returnType.annotations[len - 1] = a;
+ }
+ }
+ private static void applyAnnotationToVarDecl(EclipseNode typeNode, Argument arg, String annType, boolean typeUse) {
+ if (annType == null) return;
+
+ int partCount = 1;
+ for (int i = 0; i < annType.length(); i++) if (annType.charAt(i) == '.') partCount++;
+ long[] ps = new long[partCount];
+ Arrays.fill(ps, 0L);
+ Annotation ann = new MarkerAnnotation(new QualifiedTypeReference(Eclipse.fromQualifiedName(annType), ps), 0);
+
+ if (!typeUse || arg.type.getTypeName().length < 2) {
+ Annotation[] a = arg.annotations;
+ if (a == null) a = new Annotation[1];
+ else {
+ Annotation[] b = new Annotation[a.length + 1];
+ System.arraycopy(a, 0, b, 0, a.length);
+ a = b;
+ }
+ a[a.length - 1] = ann;
+ arg.annotations = a;
+ } else {
+ int len = arg.type.getTypeName().length;
+ if (arg.type.annotations == null) arg.type.annotations = new Annotation[len][];
+ Annotation[] a = arg.type.annotations[len - 1];
+ if (a == null) a = new Annotation[1];
+ else {
+ Annotation[] b = new Annotation[a.length + 1];
+ System.arraycopy(a, 0, b, 1, a.length);
+ a = b;
+ }
+ a[0] = ann;
+ arg.type.annotations[len - 1] = a;
+ }
+ }
+
public static NameReference generateQualifiedNameRef(ASTNode source, char[]... varNames) {
int pS = source.sourceStart, pE = source.sourceEnd;
long p = (long)pS << 32 | pE;
diff --git a/src/core/lombok/eclipse/handlers/EclipseSingularsRecipes.java b/src/core/lombok/eclipse/handlers/EclipseSingularsRecipes.java
index 5fe4b958..cbbd4cc8 100755
--- a/src/core/lombok/eclipse/handlers/EclipseSingularsRecipes.java
+++ b/src/core/lombok/eclipse/handlers/EclipseSingularsRecipes.java
@@ -35,6 +35,7 @@ import org.eclipse.jdt.internal.compiler.ast.ASTNode;
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.AllocationExpression;
import org.eclipse.jdt.internal.compiler.ast.Annotation;
+import org.eclipse.jdt.internal.compiler.ast.Argument;
import org.eclipse.jdt.internal.compiler.ast.Block;
import org.eclipse.jdt.internal.compiler.ast.ConditionalExpression;
import org.eclipse.jdt.internal.compiler.ast.EqualExpression;
@@ -437,7 +438,7 @@ public class EclipseSingularsRecipes {
}
}
- protected void nullBehaviorize(SingularData data, List<Statement> statements) {
+ protected void nullBehaviorize(EclipseNode typeNode, SingularData data, List<Statement> statements, Argument arg) {
NullCollectionBehavior behavior = data.getNullCollectionBehavior();
if (behavior == NullCollectionBehavior.IGNORE) {
@@ -446,9 +447,12 @@ public class EclipseSingularsRecipes {
b.statements = statements.toArray(new Statement[statements.size()]);
statements.clear();
statements.add(new IfStatement(isNotNull, b, 0, 0));
+ EclipseHandlerUtil.createRelevantNullableAnnotation(typeNode, arg);
return;
}
+ EclipseHandlerUtil.createRelevantNonNullAnnotation(typeNode, arg);
+
String exceptionTypeStr = behavior.getExceptionType();
StringLiteral message = new StringLiteral(behavior.toExceptionMessage(new String(data.getPluralName())).toCharArray(), 0, 0, 0);
if (exceptionTypeStr != null) {
diff --git a/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java b/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java
index 46474b07..959b2cae 100755
--- a/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java
+++ b/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java
@@ -557,6 +557,7 @@ public class HandleEqualsAndHashCode extends EclipseAnnotationHandler<EqualsAndH
method.arguments = new Argument[] {new Argument(new char[] { 'o' }, 0, objectRef, Modifier.FINAL)};
method.arguments[0].sourceStart = pS; method.arguments[0].sourceEnd = pE;
if (!onParam.isEmpty()) method.arguments[0].annotations = onParam.toArray(new Annotation[0]);
+ EclipseHandlerUtil.createRelevantNullableAnnotation(type, method.arguments[0]);
setGeneratedBy(method.arguments[0], source);
List<Statement> statements = new ArrayList<Statement>();
@@ -806,6 +807,7 @@ public class HandleEqualsAndHashCode extends EclipseAnnotationHandler<EqualsAndH
method.arguments = new Argument[] {new Argument(otherName, 0, objectRef, Modifier.FINAL)};
method.arguments[0].sourceStart = pS; method.arguments[0].sourceEnd = pE;
if (!onParam.isEmpty()) method.arguments[0].annotations = onParam.toArray(new Annotation[0]);
+ EclipseHandlerUtil.createRelevantNullableAnnotation(type, method.arguments[0]);
setGeneratedBy(method.arguments[0], source);
SingleNameReference otherRef = new SingleNameReference(otherName, p);
diff --git a/src/core/lombok/eclipse/handlers/HandleToString.java b/src/core/lombok/eclipse/handlers/HandleToString.java
index 39fd5937..a6bcb24f 100644
--- a/src/core/lombok/eclipse/handlers/HandleToString.java
+++ b/src/core/lombok/eclipse/handlers/HandleToString.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2019 The Project Lombok Authors.
+ * Copyright (C) 2009-2020 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
@@ -315,6 +315,7 @@ public class HandleToString extends EclipseAnnotationHandler<ToString> {
method.bodyStart = method.declarationSourceStart = method.sourceStart = source.sourceStart;
method.bodyEnd = method.declarationSourceEnd = method.sourceEnd = source.sourceEnd;
method.statements = new Statement[] { returnStatement };
+ EclipseHandlerUtil.createRelevantNonNullAnnotation(type, method);
return method;
}
diff --git a/src/core/lombok/eclipse/handlers/HandleWith.java b/src/core/lombok/eclipse/handlers/HandleWith.java
index 8c8c3712..4771818d 100644
--- a/src/core/lombok/eclipse/handlers/HandleWith.java
+++ b/src/core/lombok/eclipse/handlers/HandleWith.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012-2019 The Project Lombok Authors.
+ * Copyright (C) 2012-2020 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
@@ -287,6 +287,8 @@ public class HandleWith extends EclipseAnnotationHandler<With> {
}
param.annotations = copyAnnotations(source, copyableAnnotations, onParam.toArray(new Annotation[0]));
+ EclipseHandlerUtil.createRelevantNonNullAnnotation(fieldNode, method);
+
method.traverse(new SetGeneratedByVisitor(source), parent.scope);
return method;
}
diff --git a/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSingularizer.java b/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSingularizer.java
index b067ad80..5d656c91 100755
--- a/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSingularizer.java
+++ b/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSingularizer.java
@@ -196,16 +196,18 @@ abstract class EclipseGuavaSingularizer extends EclipseSingularizer {
thisDotFieldDotAddAll.selector = (getAddMethodName() + "All").toCharArray();
statements.add(thisDotFieldDotAddAll);
- nullBehaviorize(data, statements);
+ TypeReference paramType;
+ paramType = new QualifiedTypeReference(fromQualifiedName(getAddAllTypeName()), NULL_POSS);
+ paramType = addTypeArgs(getTypeArgumentsCount(), true, builderType, paramType, data.getTypeArgs());
+ Argument param = new Argument(data.getPluralName(), 0, paramType, ClassFileConstants.AccFinal);
+
+ nullBehaviorize(builderType, data, statements, param);
if (returnStatement != null) statements.add(returnStatement);
md.statements = statements.toArray(new Statement[0]);
- TypeReference paramType;
- paramType = new QualifiedTypeReference(fromQualifiedName(getAddAllTypeName()), NULL_POSS);
- paramType = addTypeArgs(getTypeArgumentsCount(), true, builderType, paramType, data.getTypeArgs());
- Argument param = new Argument(data.getPluralName(), 0, paramType, ClassFileConstants.AccFinal);
+
md.arguments = new Argument[] {param};
md.returnType = returnType;
char[] prefixedSelector = data.getSetterPrefix().length == 0 ? data.getPluralName() : HandlerUtil.buildAccessorName(new String(data.getSetterPrefix()), new String(data.getPluralName())).toCharArray();
diff --git a/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSetSingularizer.java b/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSetSingularizer.java
index ba447397..024f5880 100755
--- a/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSetSingularizer.java
+++ b/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSetSingularizer.java
@@ -174,14 +174,15 @@ abstract class EclipseJavaUtilListSetSingularizer extends EclipseJavaUtilSingula
thisDotFieldDotAddAll.selector = "addAll".toCharArray();
statements.add(thisDotFieldDotAddAll);
- nullBehaviorize(data, statements);
+ TypeReference paramType = new QualifiedTypeReference(TypeConstants.JAVA_UTIL_COLLECTION, NULL_POSS);
+ paramType = addTypeArgs(1, true, builderType, paramType, data.getTypeArgs());
+ Argument param = new Argument(data.getPluralName(), 0, paramType, ClassFileConstants.AccFinal);
+
+ nullBehaviorize(builderType, data, statements, param);
if (returnStatement != null) statements.add(returnStatement);
md.statements = statements.toArray(new Statement[0]);
- TypeReference paramType = new QualifiedTypeReference(TypeConstants.JAVA_UTIL_COLLECTION, NULL_POSS);
- paramType = addTypeArgs(1, true, builderType, paramType, data.getTypeArgs());
- Argument param = new Argument(data.getPluralName(), 0, paramType, ClassFileConstants.AccFinal);
md.arguments = new Argument[] {param};
md.returnType = returnType;
char[] prefixedSelector = data.getSetterPrefix().length == 0 ? data.getPluralName() : HandlerUtil.buildAccessorName(new String(data.getSetterPrefix()), new String(data.getPluralName())).toCharArray();
diff --git a/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilMapSingularizer.java b/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilMapSingularizer.java
index e91c6616..843fd073 100755
--- a/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilMapSingularizer.java
+++ b/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilMapSingularizer.java
@@ -306,15 +306,16 @@ public class EclipseJavaUtilMapSingularizer extends EclipseJavaUtilSingularizer
forEach.action = forEachContent;
statements.add(forEach);
- nullBehaviorize(data, statements);
+ TypeReference paramType = new QualifiedTypeReference(JAVA_UTIL_MAP, NULL_POSS);
+ paramType = addTypeArgs(2, true, builderType, paramType, data.getTypeArgs());
+ Argument param = new Argument(data.getPluralName(), 0, paramType, ClassFileConstants.AccFinal);
+
+ nullBehaviorize(builderType, data, statements, param);
if (returnStatement != null) statements.add(returnStatement);
md.statements = statements.toArray(new Statement[0]);
- TypeReference paramType = new QualifiedTypeReference(JAVA_UTIL_MAP, NULL_POSS);
- paramType = addTypeArgs(2, true, builderType, paramType, data.getTypeArgs());
- Argument param = new Argument(data.getPluralName(), 0, paramType, ClassFileConstants.AccFinal);
md.arguments = new Argument[] {param};
md.returnType = returnType;