From 26cc8af4d8b0bc7944b5a7137e9e1c77f2f3cf43 Mon Sep 17 00:00:00 2001 From: Jan Rieke Date: Fri, 12 Mar 2021 09:55:44 +0100 Subject: [PATCH] [fixes #2704] SuperBuilder: avoid NPE on existing constructors --- .../eclipse/handlers/HandleSuperBuilder.java | 2 +- .../SuperBuilderWithExistingConstuctor.java | 39 +++++++++++++++++++ .../SuperBuilderWithExistingConstuctor.java | 32 +++++++++++++++ .../SuperBuilderWithExistingConstuctor.java | 5 +++ 4 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 test/transform/resource/after-delombok/SuperBuilderWithExistingConstuctor.java create mode 100644 test/transform/resource/after-ecj/SuperBuilderWithExistingConstuctor.java create mode 100644 test/transform/resource/before/SuperBuilderWithExistingConstuctor.java diff --git a/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java b/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java index d9c8946f8b..870b1ac1a4 100644 --- a/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java +++ b/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java @@ -1206,7 +1206,7 @@ private boolean constructorExists(EclipseNode type, String builderClassName) { if ((def.bits & ASTNode.IsDefaultConstructor) != 0) continue; if (!def.isConstructor()) continue; if (isTolerate(type, def)) continue; - if (def.arguments.length != 1) continue; + if (def.arguments == null || def.arguments.length != 1) continue; // Cannot use typeMatches() here, because the parameter could be fully-qualified, partially-qualified, or not qualified. // A string-compare of the last part should work. If it's a false-positive, users could still @Tolerate it. diff --git a/test/transform/resource/after-delombok/SuperBuilderWithExistingConstuctor.java b/test/transform/resource/after-delombok/SuperBuilderWithExistingConstuctor.java new file mode 100644 index 0000000000..c23c24db96 --- /dev/null +++ b/test/transform/resource/after-delombok/SuperBuilderWithExistingConstuctor.java @@ -0,0 +1,39 @@ +public class SuperBuilderWithExistingConstuctor { + public SuperBuilderWithExistingConstuctor() { + } + @java.lang.SuppressWarnings("all") + public static abstract class SuperBuilderWithExistingConstuctorBuilder> { + @java.lang.SuppressWarnings("all") + protected abstract B self(); + @java.lang.SuppressWarnings("all") + public abstract C build(); + @java.lang.Override + @java.lang.SuppressWarnings("all") + public java.lang.String toString() { + return "SuperBuilderWithExistingConstuctor.SuperBuilderWithExistingConstuctorBuilder()"; + } + } + @java.lang.SuppressWarnings("all") + private static final class SuperBuilderWithExistingConstuctorBuilderImpl extends SuperBuilderWithExistingConstuctor.SuperBuilderWithExistingConstuctorBuilder { + @java.lang.SuppressWarnings("all") + private SuperBuilderWithExistingConstuctorBuilderImpl() { + } + @java.lang.Override + @java.lang.SuppressWarnings("all") + protected SuperBuilderWithExistingConstuctor.SuperBuilderWithExistingConstuctorBuilderImpl self() { + return this; + } + @java.lang.Override + @java.lang.SuppressWarnings("all") + public SuperBuilderWithExistingConstuctor build() { + return new SuperBuilderWithExistingConstuctor(this); + } + } + @java.lang.SuppressWarnings("all") + protected SuperBuilderWithExistingConstuctor(final SuperBuilderWithExistingConstuctor.SuperBuilderWithExistingConstuctorBuilder b) { + } + @java.lang.SuppressWarnings("all") + public static SuperBuilderWithExistingConstuctor.SuperBuilderWithExistingConstuctorBuilder builder() { + return new SuperBuilderWithExistingConstuctor.SuperBuilderWithExistingConstuctorBuilderImpl(); + } +} \ No newline at end of file diff --git a/test/transform/resource/after-ecj/SuperBuilderWithExistingConstuctor.java b/test/transform/resource/after-ecj/SuperBuilderWithExistingConstuctor.java new file mode 100644 index 0000000000..676e184b8c --- /dev/null +++ b/test/transform/resource/after-ecj/SuperBuilderWithExistingConstuctor.java @@ -0,0 +1,32 @@ +public @lombok.experimental.SuperBuilder class SuperBuilderWithExistingConstuctor { + public static abstract @java.lang.SuppressWarnings("all") class SuperBuilderWithExistingConstuctorBuilder> { + public SuperBuilderWithExistingConstuctorBuilder() { + super(); + } + protected abstract @java.lang.SuppressWarnings("all") B self(); + public abstract @java.lang.SuppressWarnings("all") C build(); + public @java.lang.Override @java.lang.SuppressWarnings("all") java.lang.String toString() { + return "SuperBuilderWithExistingConstuctor.SuperBuilderWithExistingConstuctorBuilder()"; + } + } + private static final @java.lang.SuppressWarnings("all") class SuperBuilderWithExistingConstuctorBuilderImpl extends SuperBuilderWithExistingConstuctor.SuperBuilderWithExistingConstuctorBuilder { + private SuperBuilderWithExistingConstuctorBuilderImpl() { + super(); + } + protected @java.lang.Override @java.lang.SuppressWarnings("all") SuperBuilderWithExistingConstuctor.SuperBuilderWithExistingConstuctorBuilderImpl self() { + return this; + } + public @java.lang.Override @java.lang.SuppressWarnings("all") SuperBuilderWithExistingConstuctor build() { + return new SuperBuilderWithExistingConstuctor(this); + } + } + public SuperBuilderWithExistingConstuctor() { + super(); + } + protected @java.lang.SuppressWarnings("all") SuperBuilderWithExistingConstuctor(final SuperBuilderWithExistingConstuctor.SuperBuilderWithExistingConstuctorBuilder b) { + super(); + } + public static @java.lang.SuppressWarnings("all") SuperBuilderWithExistingConstuctor.SuperBuilderWithExistingConstuctorBuilder builder() { + return new SuperBuilderWithExistingConstuctor.SuperBuilderWithExistingConstuctorBuilderImpl(); + } +} \ No newline at end of file diff --git a/test/transform/resource/before/SuperBuilderWithExistingConstuctor.java b/test/transform/resource/before/SuperBuilderWithExistingConstuctor.java new file mode 100644 index 0000000000..13f9763217 --- /dev/null +++ b/test/transform/resource/before/SuperBuilderWithExistingConstuctor.java @@ -0,0 +1,5 @@ +@lombok.experimental.SuperBuilder +public class SuperBuilderWithExistingConstuctor { + public SuperBuilderWithExistingConstuctor() { + } +}