aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorReinier Zwitserloot <r.zwitserloot@projectlombok.org>2021-04-18 06:33:36 +0200
committerReinier Zwitserloot <r.zwitserloot@projectlombok.org>2021-04-18 06:33:36 +0200
commit8e7fcac2e39f7eb8809130ae73b4d17965a5d9f2 (patch)
tree04a4e22b84b8a89b9f0327935ef7a264a7b21908
parent3f6d668f8343d2f78736ea36c7b5aa33013fea73 (diff)
downloadlombok-8e7fcac2e39f7eb8809130ae73b4d17965a5d9f2.tar.gz
lombok-8e7fcac2e39f7eb8809130ae73b4d17965a5d9f2.tar.bz2
lombok-8e7fcac2e39f7eb8809130ae73b4d17965a5d9f2.zip
[records] [@NonNull] slight refactor to ensure any generated canonical constructor is visible to downstream APs
We used to remove the canonical constructor on a record that javac generates, and replace it with our own, as we put null checks in it. However, the type mirrors and such Annotation Processors use already have the implicit canonical constructor available. Instead of trying to remove those, let's just take the existing implicit constructor and add to that (and mark it explicit, of course).
-rw-r--r--src/core/lombok/javac/handlers/HandleNonNull.java34
-rw-r--r--test/transform/resource/after-delombok/NonNullExistingConstructorOnRecord.java12
2 files changed, 30 insertions, 16 deletions
diff --git a/src/core/lombok/javac/handlers/HandleNonNull.java b/src/core/lombok/javac/handlers/HandleNonNull.java
index 786a7659..fe66432a 100644
--- a/src/core/lombok/javac/handlers/HandleNonNull.java
+++ b/src/core/lombok/javac/handlers/HandleNonNull.java
@@ -71,7 +71,7 @@ import lombok.spi.Provides;
@Provides
@HandlerPriority(value = 512) // 2^9; onParameter=@__(@NonNull) has to run first.
public class HandleNonNull extends JavacAnnotationHandler<NonNull> {
- private JCMethodDecl createRecordArgslessConstructor(JavacNode typeNode, JavacNode source) {
+ private JCMethodDecl createRecordArgslessConstructor(JavacNode typeNode, JavacNode source, JCMethodDecl existingCtr) {
JavacTreeMaker maker = typeNode.getTreeMaker();
java.util.List<JCVariableDecl> fields = new ArrayList<JCVariableDecl>();
@@ -94,8 +94,18 @@ public class HandleNonNull extends JavacAnnotationHandler<NonNull> {
JCModifiers mods = maker.Modifiers(toJavacModifier(AccessLevel.PUBLIC) | COMPACT_RECORD_CONSTRUCTOR, List.<JCAnnotation>nil());
JCBlock body = maker.Block(0L, List.<JCStatement>nil());
- JCMethodDecl constr = maker.MethodDef(mods, typeNode.toName("<init>"), null, List.<JCTypeParameter>nil(), params.toList(), List.<JCExpression>nil(), body, null);
- return recursiveSetGeneratedBy(constr, source);
+ if (existingCtr == null) {
+ JCMethodDecl constr = maker.MethodDef(mods, typeNode.toName("<init>"), null, List.<JCTypeParameter>nil(), params.toList(), List.<JCExpression>nil(), body, null);
+ return recursiveSetGeneratedBy(constr, source);
+ } else {
+ existingCtr.mods = mods;
+ existingCtr.params = params.toList();
+ existingCtr.body = body;
+ existingCtr = recursiveSetGeneratedBy(existingCtr, source);
+ addSuppressWarningsAll(existingCtr.mods, typeNode, typeNode.getNodeFor(getGeneratedBy(existingCtr)), typeNode.getContext());
+ addGenerated(existingCtr.mods, typeNode, typeNode.getNodeFor(getGeneratedBy(existingCtr)), typeNode.getContext());
+ return existingCtr;
+ }
}
/**
@@ -113,16 +123,17 @@ public class HandleNonNull extends JavacAnnotationHandler<NonNull> {
JCClassDecl cDecl = (JCClassDecl) typeNode.get();
if ((cDecl.mods.flags & RECORD) == 0) return answer;
- ListBuffer<JCTree> newDefs = new ListBuffer<JCTree>();
boolean generateConstructor = false;
+ JCMethodDecl existingCtr = null;
+
for (JCTree def : cDecl.defs) {
- boolean remove = false;
if (def instanceof JCMethodDecl) {
JCMethodDecl md = (JCMethodDecl) def;
if (md.name.contentEquals("<init>")) {
if ((md.mods.flags & Flags.GENERATEDCONSTR) != 0) {
- remove = true;
+ existingCtr = md;
+ existingCtr.mods.flags = existingCtr.mods.flags & ~Flags.GENERATEDCONSTR;
generateConstructor = true;
} else {
if (!isTolerate(typeNode, md)) {
@@ -134,13 +145,16 @@ public class HandleNonNull extends JavacAnnotationHandler<NonNull> {
}
}
}
- if (!remove) newDefs.append(def);
}
if (generateConstructor) {
- cDecl.defs = newDefs.toList();
- JCMethodDecl ctr = createRecordArgslessConstructor(typeNode, source);
- injectMethod(typeNode, ctr);
+ JCMethodDecl ctr;
+ if (existingCtr != null) {
+ ctr = createRecordArgslessConstructor(typeNode, source, existingCtr);
+ } else {
+ ctr = createRecordArgslessConstructor(typeNode, source, null);
+ injectMethod(typeNode, ctr);
+ }
answer = answer.prepend(ctr);
}
diff --git a/test/transform/resource/after-delombok/NonNullExistingConstructorOnRecord.java b/test/transform/resource/after-delombok/NonNullExistingConstructorOnRecord.java
index 45364815..dec91261 100644
--- a/test/transform/resource/after-delombok/NonNullExistingConstructorOnRecord.java
+++ b/test/transform/resource/after-delombok/NonNullExistingConstructorOnRecord.java
@@ -1,12 +1,6 @@
// version 16:
import lombok.NonNull;
public record NonNullExistingConstructorOnRecord(@NonNull String a, @NonNull String b) {
- public NonNullExistingConstructorOnRecord(@NonNull String b) {
- this("default", b);
- if (b == null) {
- throw new java.lang.NullPointerException("b is marked non-null but is null");
- }
- }
@java.lang.SuppressWarnings("all")
public NonNullExistingConstructorOnRecord {
if (a == null) {
@@ -16,4 +10,10 @@ public record NonNullExistingConstructorOnRecord(@NonNull String a, @NonNull Str
throw new java.lang.NullPointerException("b is marked non-null but is null");
}
}
+ public NonNullExistingConstructorOnRecord(@NonNull String b) {
+ this("default", b);
+ if (b == null) {
+ throw new java.lang.NullPointerException("b is marked non-null but is null");
+ }
+ }
}