[records] [@NonNull] eclipse impl onfthe @NonNull on record components feature.

All tests passing.
This commit is contained in:
Reinier Zwitserloot committed 2021-03-24 06:22:15 +01:00
1 parent 3d7754e269
commit 52a31bc4ae
76 files changed
+316 -131

No files matched your search

+1
View File
@@ -3,6 +3,7 @@ Lombok Changelog
### v1.18.19 "Edgy Guinea Pig"
* PLATFORM: JDK16 support added. [Issue #2681](https://github.com/mplushnikov/lombok-intellij-plugin/issues/2681).
* PLATFORM: All lombok features updated to act in a sane fashion with JDK16's _record_ feature. In particular, you can annotate record components with `@NonNull` to have lombok add null checks to your compact constructor (which will be created if need be).
* BUGFIX: Trying to use a lambda expression as parameter to an `@ExtensionMethod` did not work. [Issue #2741](https://github.com/rzwitserloot/lombok/issues/2741). (by __@Rawi01__).
* BUGFIX: `@SuperBuilder` with an existing constructor caused issues in eclipse. [Issue #2704](https://github.com/rzwitserloot/lombok/issues/2704). (by [@JanRieke](https://github.com/rzwitserloot/lombok/pull/2770)).
* BUGFIX: Using `@SuperBuilder` with a handwritten builder class caused issues. [Issue #2701](https://github.com/rzwitserloot/lombok/issues/2701). (by [@JanRieke](https://github.com/rzwitserloot/lombok/pull/2772)).
@@ -1888,26 +1888,6 @@ public class EclipseHandlerUtil {
return MemberExistsResult.NOT_EXISTS;
}
/**
* Checks if there is at least one constructor that is generated by lombok.
*
* @param node Any node that represents the Type (TypeDeclaration) to look in, or any child node thereof.
*/
public static boolean lombokConstructorExists(EclipseNode node) {
node = upToTypeNode(node);
if (node != null && node.get() instanceof TypeDeclaration) {
TypeDeclaration typeDecl = (TypeDeclaration) node.get();
if (typeDecl.methods != null) for (AbstractMethodDeclaration def : typeDecl.methods) {
if (!(def instanceof ConstructorDeclaration)) continue;
if ((def.bits & ASTNode.IsDefaultConstructor | IsCanonicalConstructor) != 0) continue;
if (isTolerate(node, def)) continue;
if (getGeneratedBy(def) != null) return true;
}
}
return false;
}
/**
* Inserts a field into an existing type. The type must represent a {@code TypeDeclaration}.
* The field carries the @{@link SuppressWarnings}("all") annotation.
@@ -22,11 +22,12 @@
package lombok.eclipse.handlers;
import static lombok.core.handlers.HandlerUtil.handleFlagUsage;
import static lombok.eclipse.Eclipse.isPrimitive;
import static lombok.eclipse.Eclipse.*;
import static lombok.eclipse.handlers.EclipseHandlerUtil.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
@@ -36,19 +37,28 @@ 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.CompilationUnitDeclaration;
import org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration;
import org.eclipse.jdt.internal.compiler.ast.EqualExpression;
import org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall;
import org.eclipse.jdt.internal.compiler.ast.Expression;
import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
import org.eclipse.jdt.internal.compiler.ast.FieldReference;
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.QualifiedTypeReference;
import org.eclipse.jdt.internal.compiler.ast.SingleNameReference;
import org.eclipse.jdt.internal.compiler.ast.SingleTypeReference;
import org.eclipse.jdt.internal.compiler.ast.Statement;
import org.eclipse.jdt.internal.compiler.ast.SynchronizedStatement;
import org.eclipse.jdt.internal.compiler.ast.ThisReference;
import org.eclipse.jdt.internal.compiler.ast.ThrowStatement;
import org.eclipse.jdt.internal.compiler.ast.TryStatement;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.eclipse.jdt.internal.compiler.ast.TypeReference;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import lombok.AccessLevel;
import lombok.ConfigurationKeys;
import lombok.NonNull;
import lombok.core.AST.Kind;
@@ -58,7 +68,6 @@ import lombok.eclipse.EcjAugments;
import lombok.eclipse.EclipseAST;
import lombok.eclipse.EclipseAnnotationHandler;
import lombok.eclipse.EclipseNode;
import lombok.eclipse.handlers.HandleConstructor.SkipIfConstructorExists;
import lombok.spi.Provides;
@Provides
@@ -68,7 +77,6 @@ public class HandleNonNull extends EclipseAnnotationHandler<NonNull> {
private static final char[] CHECK_NOT_NULL = "checkNotNull".toCharArray();
public static final HandleNonNull INSTANCE = new HandleNonNull();
private HandleConstructor handleConstructor = new HandleConstructor();
public void fix(EclipseNode method) {
for (EclipseNode m : method.down()) {
@@ -83,14 +91,146 @@ public class HandleNonNull extends EclipseAnnotationHandler<NonNull> {
}
}
private List<FieldDeclaration> getRecordComponents(EclipseNode typeNode) {
List<FieldDeclaration> list = new ArrayList<FieldDeclaration>();
for (EclipseNode child : typeNode.down()) {
if (child.getKind() == Kind.FIELD) {
FieldDeclaration fd = (FieldDeclaration) child.get();
if ((fd.modifiers & AccRecord) != 0) list.add(fd);
}
}
return list;
}
private EclipseNode addCompactConstructorIfNeeded(EclipseNode typeNode, EclipseNode annotationNode) {
// explicit Compact Constructor has bits set: Bit32, IsCanonicalConstructor (10).
// implicit Compact Constructor has bits set: Bit32, IsCanonicalConstructor (10), and IsImplicit (11).
// explicit constructor with long-form shows up as a normal constructor (Bit32 set, that's all), but the
// implicit CC is then also present and will presumably be stripped out in some later phase.
EclipseNode toRemove = null;
EclipseNode existingCompactConstructor = null;
List<FieldDeclaration> recordComponents = null;
for (EclipseNode child : typeNode.down()) {
if (!(child.get() instanceof ConstructorDeclaration)) continue;
ConstructorDeclaration cd = (ConstructorDeclaration) child.get();
if ((cd.bits & IsCanonicalConstructor) != 0) {
if ((cd.bits & IsImplicit) != 0) {
toRemove = child;
} else {
existingCompactConstructor = child;
}
} else {
// If this constructor has exact matching types vs. the record components,
// this is the canonical constructor in long form and we should not generate one.
if (recordComponents == null) recordComponents = getRecordComponents(typeNode);
int argLength = cd.arguments == null ? 0 : cd.arguments.length;
int compLength = recordComponents.size();
boolean isCanonical = argLength == compLength;
if (isCanonical) top: for (int i = 0; i < argLength; i++) {
TypeReference a = recordComponents.get(i).type;
TypeReference b = cd.arguments[i] == null ? null : cd.arguments[i].type;
// technically this won't match e.g. `java.lang.String` to just `String`;
// to use this feature you'll need to use the same way to write it, which seems
// like a fair requirement.
char[][] ta = getRawTypeName(a);
char[][] tb = getRawTypeName(b);
if (ta == null || tb == null || ta.length != tb.length) {
isCanonical = false;
break top;
}
for (int j = 0; j < ta.length; j++) {
if (!Arrays.equals(ta[j], tb[j])) {
isCanonical = false;
break top;
}
}
}
if (isCanonical) {
return null;
}
}
}
if (existingCompactConstructor != null) return existingCompactConstructor;
int posToInsert = -1;
TypeDeclaration td = (TypeDeclaration) typeNode.get();
if (toRemove != null) {
int idxToRemove = -1;
for (int i = 0; i < td.methods.length; i++) {
if (td.methods[i] == toRemove.get()) idxToRemove = i;
}
if (idxToRemove != -1) {
System.arraycopy(td.methods, idxToRemove + 1, td.methods, idxToRemove, td.methods.length - idxToRemove - 1);
posToInsert = td.methods.length - 1;
typeNode.removeChild(toRemove);
}
}
if (posToInsert == -1) {
AbstractMethodDeclaration[] na = new AbstractMethodDeclaration[td.methods.length + 1];
posToInsert = td.methods.length;
System.arraycopy(td.methods, 0, na, 0, posToInsert);
td.methods = na;
}
ConstructorDeclaration cd = new ConstructorDeclaration(((CompilationUnitDeclaration) typeNode.top().get()).compilationResult);
cd.modifiers = ClassFileConstants.AccPublic;
cd.bits = ASTNode.Bit32 | ECLIPSE_DO_NOT_TOUCH_FLAG | IsCanonicalConstructor;
cd.selector = td.name;
cd.constructorCall = new ExplicitConstructorCall(ExplicitConstructorCall.ImplicitSuper);
if (recordComponents == null) recordComponents = getRecordComponents(typeNode);
cd.arguments = new Argument[recordComponents.size()];
cd.statements = new Statement[recordComponents.size()];
cd.bits = IsCanonicalConstructor;
for (int i = 0; i < cd.arguments.length; i++) {
FieldDeclaration cmp = recordComponents.get(i);
cd.arguments[i] = new Argument(cmp.name, cmp.sourceStart, cmp.type, 0);
cd.arguments[i].bits = ASTNode.IsArgument | ASTNode.IgnoreRawTypeCheck | ASTNode.IsReachable;
FieldReference lhs = new FieldReference(cmp.name, 0);
lhs.receiver = new ThisReference(0, 0);
SingleNameReference rhs = new SingleNameReference(cmp.name, 0);
cd.statements[i] = new Assignment(lhs, rhs, cmp.sourceEnd);
}
setGeneratedBy(cd, annotationNode.get());
for (int i = 0; i < cd.arguments.length; i++) {
FieldDeclaration cmp = recordComponents.get(i);
cd.arguments[i].sourceStart = cmp.sourceStart;
cd.arguments[i].sourceEnd = cmp.sourceStart;
cd.arguments[i].declarationSourceEnd = cmp.sourceStart;
cd.arguments[i].declarationEnd = cmp.sourceStart;
}
td.methods[posToInsert] = cd;
cd.annotations = addSuppressWarningsAll(typeNode, cd, cd.annotations);
cd.annotations = addGenerated(typeNode, cd, cd.annotations);
return typeNode.add(cd, Kind.METHOD);
}
private static char[][] getRawTypeName(TypeReference a) {
if (a instanceof QualifiedTypeReference) return ((QualifiedTypeReference) a).tokens;
if (a instanceof SingleTypeReference) return new char[][] {((SingleTypeReference) a).token};
return null;
}
@Override public void handle(AnnotationValues<NonNull> annotation, Annotation ast, EclipseNode annotationNode) {
// Generating new methods is only possible during diet parse but modifying existing methods requires a full parse.
// As we need both for @NonNull we reset the handled flag during diet parse.
if (!annotationNode.isCompleteParse()) {
EclipseNode typeNode = upToTypeNode(annotationNode);
if (isRecordField(annotationNode.up()) && !lombokConstructorExists(typeNode)) {
handleConstructor.generateAllArgsConstructor(typeNode, AccessLevel.PUBLIC, null, SkipIfConstructorExists.NO, Collections.<Annotation>emptyList(), annotationNode);
if (annotationNode.up().getKind() == Kind.FIELD) {
//Check if this is a record and we need to generate the compact form constructor.
EclipseNode typeNode = annotationNode.up().up();
if (typeNode.getKind() == Kind.TYPE) {
if (isRecord(typeNode)) {
addCompactConstructorIfNeeded(typeNode, annotationNode);
}
}
}
EcjAugments.ASTNode_handled.clear(ast);
return;
}
@@ -98,6 +238,16 @@ public class HandleNonNull extends EclipseAnnotationHandler<NonNull> {
handle0(ast, annotationNode, false);
}
private EclipseNode findCompactConstructor(EclipseNode typeNode) {
for (EclipseNode child : typeNode.down()) {
if (!(child.get() instanceof ConstructorDeclaration)) continue;
ConstructorDeclaration cd = (ConstructorDeclaration) child.get();
if ((cd.bits & IsCanonicalConstructor) != 0 && (cd.bits & IsImplicit) == 0) return child;
}
return null;
}
private void handle0(Annotation ast, EclipseNode annotationNode, boolean force) {
handleFlagUsage(annotationNode, ConfigurationKeys.NON_NULL_FLAG_USAGE, "@NonNull");
@@ -106,13 +256,26 @@ public class HandleNonNull extends EclipseAnnotationHandler<NonNull> {
// but in that case those handlers will take care of it. However, we DO check if the annotation is applied to
// a primitive, because those handlers trigger on any annotation named @NonNull and we only want the warning
// behaviour on _OUR_ 'lombok.NonNull'.
EclipseNode fieldNode = annotationNode.up();
EclipseNode typeNode = fieldNode.up();
try {
if (isPrimitive(((AbstractVariableDeclaration) annotationNode.up().get()).type)) {
annotationNode.addWarning("@NonNull is meaningless on a primitive.");
return;
}
} catch (Exception ignore) {}
if (isRecord(typeNode)) {
// well, these kinda double as parameters (of the compact constructor), so we do some work here.
// NB:Tthe diet parse run already added an explicit compact constructor if we need to take any actions.
EclipseNode compactConstructor = findCompactConstructor(typeNode);
if (compactConstructor != null) {
addNullCheckIfNeeded((AbstractMethodDeclaration) compactConstructor.get(), (AbstractVariableDeclaration) fieldNode.get(), annotationNode);
}
}
return;
}
@@ -154,6 +317,11 @@ public class HandleNonNull extends EclipseAnnotationHandler<NonNull> {
return;
}
addNullCheckIfNeeded(declaration, param, annotationNode);
paramNode.up().rebuild();
}
private void addNullCheckIfNeeded(AbstractMethodDeclaration declaration, AbstractVariableDeclaration param, EclipseNode annotationNode) {
// Possibly, if 'declaration instanceof ConstructorDeclaration', fetch declaration.constructorCall, search it for any references to our parameter,
// and if they exist, create a new method in the class: 'private static <T> T lombok$nullCheck(T expr, String msg) {if (expr == null) throw NPE; return expr;}' and
// wrap all references to it in the super/this to a call to this method.
@@ -202,7 +370,6 @@ public class HandleNonNull extends EclipseAnnotationHandler<NonNull> {
newStatements[skipOver] = nullCheck;
declaration.statements = newStatements;
}
paramNode.up().rebuild();
}
public boolean isNullCheck(Statement stat) {
@@ -219,6 +219,8 @@ public class HandleNonNull extends JavacAnnotationHandler<NonNull> {
JCVariableDecl fDecl = (JCVariableDecl) annotationNode.up().get();
if ((fDecl.mods.flags & RECORD) != 0) {
// well, these kinda double as parameters (of the compact constructor), so we do some work here.
List<JCMethodDecl> compactConstructors = addCompactConstructorIfNeeded(annotationNode.up().up(), annotationNode);
for (JCMethodDecl ctr : compactConstructors) {
addNullCheckIfNeeded(ctr, annotationNode.up(), annotationNode);
@@ -815,9 +815,6 @@ public class PrettyPrinter extends JCTree.Visitor {
boolean argsLessConstructor = false;
if (isConstructor && (tree.mods.flags & COMPACT_RECORD_CONSTRUCTOR) != 0) {
argsLessConstructor = true;
for (JCVariableDecl param : tree.params) {
if ((param.mods.flags & GENERATED_MEMBER) == 0) argsLessConstructor = false;
}
}
boolean first = true;
@@ -120,7 +120,7 @@ public class PatchVal {
public static boolean couldBe(ImportReference[] imports, String key, TypeReference ref) {
String[] keyParts = key.split("\\.");
if (ref instanceof SingleTypeReference) {
char[] token = ((SingleTypeReference)ref).token;
char[] token = ((SingleTypeReference) ref).token;
if (!matches(keyParts[keyParts.length - 1], token)) return false;
if (imports == null) return true;
top:
@@ -140,7 +140,7 @@ public class PatchVal {
}
if (ref instanceof QualifiedTypeReference) {
char[][] tokens = ((QualifiedTypeReference)ref).tokens;
char[][] tokens = ((QualifiedTypeReference) ref).tokens;
if (keyParts.length != tokens.length) return false;
for(int i = 0; i < tokens.length; ++i) {
String part = keyParts[i];
@@ -270,7 +270,6 @@ public class PatchVal {
if (val) local.modifiers |= ClassFileConstants.AccFinal;
local.annotations = addValAnnotation(local.annotations, local.type, scope);
local.type = replacement != null ? replacement : new QualifiedTypeReference(TypeConstants.JAVA_LANG_OBJECT, poss(local.type, 3));
return false;
}
+6 -4
View File
@@ -60,10 +60,12 @@ public class Eclipse {
*/
public static final int ECLIPSE_DO_NOT_TOUCH_FLAG = ASTNode.Bit24;
/* This section includes flags that would ordinarily be in ClassFileConstants, but which are 'too new' (we don't compile against older versions of ecj/eclipse for compatibility). */
public static final int AccRecord = ASTNode.Bit25;
public static final int IsCanonicalConstructor = ASTNode.Bit10; // For record declarations, and presumably later on any constructor matching the destructor.
public static final int IsImplicit = ASTNode.Bit11; // the generated statements in the compact constructor of a record.
/* This section includes flags that are in ecj files too new vs. the deps we compile against.
* Specifically: org.eclipse.jdt.internal.compiler.ast.ASTNode and org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers
*/
public static final int AccRecord = ASTNode.Bit25; // ECM.AccRecord
public static final int IsCanonicalConstructor = ASTNode.Bit10; // ASTNode.IsCanonicalConstructor
public static final int IsImplicit = ASTNode.Bit11; // ASTNode.IsImplicit
private static final Pattern SPLIT_AT_DOT = Pattern.compile("\\.");
+6 -1
View File
@@ -156,7 +156,12 @@ public class RunTestsViaEcj extends AbstractRunTests {
CompilationUnitDeclaration cud = compilationUnit_.get();
if (cud == null) result.append("---- No CompilationUnit provided by ecj ----");
else result.append(cud.toString());
else {
String output = cud.toString();
// starting somewhere around ecj16, the print code is a bit too cavalier with printing modifiers.
output = output.replace("non-sealed @val", "@val");
result.append(output);
}
if (eclipseAvailable()) {
EclipseDomConversion.toDomAst(cud, sourceArray);
@@ -1,6 +1,6 @@
// version 14:
import java.util.List;
record BuilderSimpleOnRecord<T>(List<T> l, String a) {
public record BuilderSimpleOnRecord<T>(List<T> l, String a) {
@java.lang.SuppressWarnings("all")
protected static class BuilderSimpleOnRecordBuilder<T> {
@java.lang.SuppressWarnings("all")
@@ -1,7 +1,7 @@
// version 14:
import java.util.Collection;
import java.util.List;
record BuilderSingularOnRecord<T>(List<T> children, Collection<? extends Number> scarves, @SuppressWarnings("all") List rawList) {
public record BuilderSingularOnRecord<T>(List<T> children, Collection<? extends Number> scarves, @SuppressWarnings("all") List rawList) {
@java.lang.SuppressWarnings("all")
public static class BuilderSingularOnRecordBuilder<T> {
@java.lang.SuppressWarnings("all")
@@ -1,3 +1,3 @@
// version 14:
record ConstructorsOnRecord(String a, String b) {
public record ConstructorsOnRecord(String a, String b) {
}
@@ -1,3 +1,3 @@
// version 14:
record DataOnRecord(String a, String b) {
public record DataOnRecord(String a, String b) {
}
@@ -1,3 +1,3 @@
// version 14:
record EqualsAndHashCodeOnRecord(String a, String b) {
public record EqualsAndHashCodeOnRecord(String a, String b) {
}
@@ -1,3 +1,3 @@
// version 14:
record FieldDefaultsOnRecord(String a, String b) {
public record FieldDefaultsOnRecord(String a, String b) {
}
@@ -1,5 +1,5 @@
// version 14:
record FieldNameConstantsOnRecord(String iAmADvdPlayer, int $skipMe, int andMe, String butPrintMePlease) {
public record FieldNameConstantsOnRecord(String iAmADvdPlayer, int $skipMe, int andMe, String butPrintMePlease) {
static double skipMeToo;
@java.lang.SuppressWarnings("all")
static final class Fields {
@@ -1,3 +1,3 @@
// version 14:
record GetterOnRecord(String a, String b) {
public record GetterOnRecord(String a, String b) {
}
@@ -1,3 +1,3 @@
// version 14:
record LoggerConfigOnRecord(String a, String b) {
public record LoggerConfigOnRecord(String a, String b) {
}
@@ -1,5 +1,5 @@
// version 16: the SuppressWarnings is not emitted in java14/15 to work around a javac bug.
record LoggerSlf4jOnRecord(String a, String b) {
public record LoggerSlf4jOnRecord(String a, String b) {
@java.lang.SuppressWarnings("all")
private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LoggerSlf4jOnRecord.class);
}
@@ -1,14 +1,14 @@
// version 14:
// version 16:
import lombok.NonNull;
record NonNullOnRecord(@NonNull String a, @NonNull String b) {
public NonNullOnRecord(@NonNull String b) {
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 NonNullOnRecord {
public NonNullExistingConstructorOnRecord {
if (a == null) {
throw new java.lang.NullPointerException("a is marked non-null but is null");
}
@@ -1,6 +1,6 @@
// version 14:
// version 16:
import lombok.NonNull;
record NonNullOnRecord(@NonNull String a, @NonNull String b) {
public record NonNullOnRecord(@NonNull String a, @NonNull String b) {
@java.lang.SuppressWarnings("all")
public NonNullOnRecord {
if (a == null) {
@@ -1,4 +1,4 @@
// version 14:
// version 16:
import lombok.NonNull;
record NonNullOnRecord2(@NonNull String a) {
public NonNullOnRecord2 {
@@ -1,6 +1,6 @@
// version 14:
import lombok.NonNull;
record NonNullOnRecord3(@NonNull String a) {
public record NonNullOnRecord3(@NonNull String a) {
public NonNullOnRecord3(String a) {
this.a = a;
}
@@ -1,3 +1,3 @@
// version 14:
record SetterOnRecord(String a, String b) {
public record SetterOnRecord(String a, String b) {
}
@@ -1,5 +1,5 @@
// version 14:
record SynchronizedInRecord(String a, String b) {
public record SynchronizedInRecord(String a, String b) {
public void foo() {
String foo = "bar";
}
@@ -1,3 +1,3 @@
// version 14:
record ToStringOnRecord(String a, String b) {
public record ToStringOnRecord(String a, String b) {
}
@@ -1,3 +1,3 @@
// version 14:
record UtilityClassOnRecord(String a, String b) {
public record UtilityClassOnRecord(String a, String b) {
}
@@ -1,3 +1,3 @@
// version 14:
record ValueOnRecord(String a, String b) {
public record ValueOnRecord(String a, String b) {
}
@@ -1,5 +1,5 @@
// version 14:
record WithByOnRecord(String a, String b) {
public record WithByOnRecord(String a, String b) {
@java.lang.SuppressWarnings("all")
public WithByOnRecord withABy(final java.util.function.Function<? super String, ? extends String> transformer) {
return new WithByOnRecord(transformer.apply(this.a), this.b);
@@ -1,5 +1,5 @@
// version 14:
record WithByOnRecordComponent(String a, String b) {
public record WithByOnRecordComponent(String a, String b) {
@java.lang.SuppressWarnings("all")
public WithByOnRecordComponent withABy(final java.util.function.Function<? super String, ? extends String> transformer) {
return new WithByOnRecordComponent(transformer.apply(this.a), this.b);
@@ -1,5 +1,5 @@
// version 14:
record WithOnRecord(String a, String b) {
public record WithOnRecord(String a, String b) {
/**
* @return a clone of this object, except with this updated property (returns {@code this} if an identical value is passed).
*/
@@ -1,5 +1,5 @@
// version 14:
record WithOnRecordComponent(String a, String b) {
public record WithOnRecordComponent(String a, String b) {
/**
* @return a clone of this object, except with this updated property (returns {@code this} if an identical value is passed).
*/
@@ -1,16 +1,22 @@
// version 14:
import java.util.List;
@lombok.Builder(access = lombok.AccessLevel.PROTECTED) record BuilderSimpleOnRecord(List l, String a)<T> {
public @lombok.Builder(access = lombok.AccessLevel.PROTECTED) record BuilderSimpleOnRecord(List l, String a)<T> {
protected static @java.lang.SuppressWarnings("all") class BuilderSimpleOnRecordBuilder<T> {
private @java.lang.SuppressWarnings("all") List<T> l;
private @java.lang.SuppressWarnings("all") String a;
@java.lang.SuppressWarnings("all") BuilderSimpleOnRecordBuilder() {
super();
}
/**
* @return {@code this}.
*/
public @java.lang.SuppressWarnings("all") BuilderSimpleOnRecord.BuilderSimpleOnRecordBuilder<T> l(final List<T> l) {
this.l = l;
return this;
}
/**
* @return {@code this}.
*/
public @java.lang.SuppressWarnings("all") BuilderSimpleOnRecord.BuilderSimpleOnRecordBuilder<T> a(final String a) {
this.a = a;
return this;
@@ -3,7 +3,7 @@ import java.util.Collection;
import java.util.List;
import lombok.Builder;
import lombok.Singular;
@Builder record BuilderSingularOnRecord(List children, Collection scarves, List rawList)<T> {
public @Builder record BuilderSingularOnRecord(List children, Collection scarves, List rawList)<T> {
public static @java.lang.SuppressWarnings("all") class BuilderSingularOnRecordBuilder<T> {
private @java.lang.SuppressWarnings("all") java.util.ArrayList<T> children;
private @java.lang.SuppressWarnings("all") java.util.ArrayList<Number> scarves;
@@ -2,7 +2,7 @@
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import lombok.RequiredArgsConstructor;
@AllArgsConstructor @RequiredArgsConstructor @NoArgsConstructor record ConstructorsOnRecord(String a, String b) {
public @AllArgsConstructor @RequiredArgsConstructor @NoArgsConstructor record ConstructorsOnRecord(String a, String b) {
/* Implicit */ private final String a;
/* Implicit */ private final String b;
public ConstructorsOnRecord(String a, String b) {
@@ -1,6 +1,6 @@
// version 14:
import lombok.Data;
@Data record DataOnRecord(String a, String b) {
public @Data record DataOnRecord(String a, String b) {
/* Implicit */ private final String a;
/* Implicit */ private final String b;
public DataOnRecord(String a, String b) {
@@ -1,6 +1,6 @@
// version 14:
import lombok.EqualsAndHashCode;
@EqualsAndHashCode record EqualsAndHashCodeOnRecord(String a, String b) {
public @EqualsAndHashCode record EqualsAndHashCodeOnRecord(String a, String b) {
/* Implicit */ private final String a;
/* Implicit */ private final String b;
public EqualsAndHashCodeOnRecord(String a, String b) {
@@ -1,5 +1,5 @@
// version 14:
@lombok.experimental.FieldDefaults(makeFinal = true) record FieldDefaultsOnRecord(String a, String b) {
public @lombok.experimental.FieldDefaults(makeFinal = true) record FieldDefaultsOnRecord(String a, String b) {
/* Implicit */ private final String a;
/* Implicit */ private final String b;
public FieldDefaultsOnRecord(String a, String b) {
@@ -1,7 +1,7 @@
// version 14:
import lombok.experimental.FieldNameConstants;
import lombok.AccessLevel;
@FieldNameConstants(level = AccessLevel.PACKAGE) record FieldNameConstantsOnRecord(String iAmADvdPlayer, int $skipMe, int andMe, String butPrintMePlease) {
public @FieldNameConstants(level = AccessLevel.PACKAGE) record FieldNameConstantsOnRecord(String iAmADvdPlayer, int $skipMe, int andMe, String butPrintMePlease) {
static final @java.lang.SuppressWarnings("all") class Fields {
public static final java.lang.String iAmADvdPlayer = "iAmADvdPlayer";
public static final java.lang.String butPrintMePlease = "butPrintMePlease";
@@ -1,6 +1,6 @@
// version 14:
import lombok.Getter;
@Getter record GetterOnRecord(String a, String b) {
public @Getter record GetterOnRecord(String a, String b) {
/* Implicit */ private final String a;
/* Implicit */ private final String b;
public GetterOnRecord(String a, String b) {
@@ -1,6 +1,6 @@
// version 14:
import lombok.extern.slf4j.Slf4j;
@Slf4j record LoggerConfigOnRecord(String a, String b) {
public @Slf4j record LoggerConfigOnRecord(String a, String b) {
/* Implicit */ private final String a;
/* Implicit */ private final String b;
public LoggerConfigOnRecord(String a, String b) {
@@ -1,6 +1,6 @@
// version 14:
import lombok.extern.slf4j.Slf4j;
@Slf4j record LoggerSlf4jOnRecord(org log, String a) {
public @Slf4j record LoggerSlf4jOnRecord(org log, String a) {
private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LoggerSlf4jOnRecord.class);
/* Implicit */ private final String a;
/* Implicit */ private final String b;
@@ -1,21 +1,16 @@
// version 14:
import lombok.NonNull;
record NonNullOnRecord(String a, String b) {
public record NonNullExistingConstructorOnRecord(String a, String b) {
/* Implicit */ private final String a;
/* Implicit */ private final String b;
public NonNullOnRecord(String a, String b) {
super();
.a = a;
.b = b;
}
public NonNullOnRecord(@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");
}
}
public @java.lang.SuppressWarnings("all") NonNullOnRecord(final String a, final String b) {
public @java.lang.SuppressWarnings("all") NonNullExistingConstructorOnRecord(@NonNull String a, @NonNull String b) {
super();
if ((a == null))
{
@@ -1,21 +1,9 @@
// version 14:
import lombok.NonNull;
record NonNullOnRecord(String a, String b) {
public record NonNullOnRecord(String a, String b) {
/* Implicit */ private final String a;
/* Implicit */ private final String b;
public NonNullOnRecord(String a, String b) {
super();
.a = a;
.b = b;
}
public void method(@NonNull String param) {
if ((param == null))
{
throw new java.lang.NullPointerException("param is marked non-null but is null");
}
String asd = "a";
}
public @java.lang.SuppressWarnings("all") NonNullOnRecord(final String a, final String b) {
public @java.lang.SuppressWarnings("all") NonNullOnRecord(@NonNull String a, @NonNull String b) {
super();
if ((a == null))
{
@@ -0,0 +1,14 @@
// version 14:
import lombok.NonNull;
record NonNullOnRecord2(String a) {
/* Implicit */ private final String a;
public NonNullOnRecord2(@NonNull String a) {
super();
if ((a == null))
{
throw new java.lang.NullPointerException("a is marked non-null but is null");
}
System.out.println("Hello");
this.a = a;
}
}
@@ -0,0 +1,20 @@
// version 14:
import lombok.NonNull;
public record NonNullOnRecord3(String a) {
/* Implicit */ private final String a;
public NonNullOnRecord3(String a) {
super();
.a = a;
}
public NonNullOnRecord3(String a) {
super();
this.a = a;
}
public void method(@NonNull String param) {
if ((param == null))
{
throw new java.lang.NullPointerException("param is marked non-null but is null");
}
String asd = "a";
}
}
@@ -1,6 +1,6 @@
// version 14:
import lombok.Setter;
@Setter record SetterOnRecord(String a, String b) {
public @Setter record SetterOnRecord(String a, String b) {
/* Implicit */ private final String a;
/* Implicit */ private final String b;
public SetterOnRecord(String a, String b) {
@@ -1,5 +1,5 @@
import lombok.Synchronized;
record SynchronizedInRecord(java $lock, String a) {
public record SynchronizedInRecord(java $lock, String a) {
private final java.lang.Object $lock = new java.lang.Object[0];
/* Implicit */ private final String a;
/* Implicit */ private final String b;
@@ -1,6 +1,6 @@
// version 14:
import lombok.ToString;
@ToString record ToStringOnRecord(String a, String b) {
public @ToString record ToStringOnRecord(String a, String b) {
/* Implicit */ private final String a;
/* Implicit */ private final String b;
public ToStringOnRecord(String a, String b) {
@@ -1,6 +1,6 @@
// version 14:
import lombok.experimental.UtilityClass;
@UtilityClass record UtilityClassOnRecord(String a, String b) {
public @UtilityClass record UtilityClassOnRecord(String a, String b) {
/* Implicit */ private final String a;
/* Implicit */ private final String b;
public UtilityClassOnRecord(String a, String b) {
@@ -1,6 +1,6 @@
// version 14:
import lombok.Value;
@Value record ValueOnRecord(String a, String b) {
public @Value record ValueOnRecord(String a, String b) {
/* Implicit */ private final String a;
/* Implicit */ private final String b;
public ValueOnRecord(String a, String b) {
@@ -1,6 +1,6 @@
// version 14:
import lombok.experimental.WithBy;
@WithBy record WithByOnRecord(String a, String b) {
public @WithBy record WithByOnRecord(String a, String b) {
/* Implicit */ private final String a;
/* Implicit */ private final String b;
public WithByOnRecord(String a, String b) {
@@ -1,6 +1,6 @@
// version 14:
import lombok.experimental.WithBy;
record WithByOnRecordComponent(String a, String b) {
public record WithByOnRecordComponent(String a, String b) {
/* Implicit */ private final String a;
/* Implicit */ private final String b;
public WithByOnRecordComponent( String a, String b) {
@@ -1,6 +1,6 @@
// version 14:
import lombok.With;
@With record WithOnRecord(String a, String b) {
public @With record WithOnRecord(String a, String b) {
/* Implicit */ private final String a;
/* Implicit */ private final String b;
public WithOnRecord(String a, String b) {
@@ -8,9 +8,15 @@ import lombok.With;
.a = a;
.b = b;
}
/**
* @return a clone of this object, except with this updated property (returns {@code this} if an identical value is passed).
*/
public @java.lang.SuppressWarnings("all") WithOnRecord withA(final String a) {
return ((this.a == a) ? this : new WithOnRecord(a, this.b));
}
/**
* @return a clone of this object, except with this updated property (returns {@code this} if an identical value is passed).
*/
public @java.lang.SuppressWarnings("all") WithOnRecord withB(final String b) {
return ((this.b == b) ? this : new WithOnRecord(this.a, b));
}
@@ -1,6 +1,6 @@
// version 14:
import lombok.With;
record WithOnRecordComponent(String a, String b) {
public record WithOnRecordComponent(String a, String b) {
/* Implicit */ private final String a;
/* Implicit */ private final String b;
public WithOnRecordComponent( String a, String b) {
@@ -8,6 +8,9 @@ record WithOnRecordComponent(String a, String b) {
.a = a;
.b = b;
}
/**
* @return a clone of this object, except with this updated property (returns {@code this} if an identical value is passed).
*/
public @java.lang.SuppressWarnings("all") WithOnRecordComponent withA(final String a) {
return ((this.a == a) ? this : new WithOnRecordComponent(a, this.b));
}
@@ -3,5 +3,5 @@
import java.util.List;
@lombok.Builder(access = lombok.AccessLevel.PROTECTED)
record BuilderSimpleOnRecord<T>(List<T> l, String a) {
public record BuilderSimpleOnRecord<T>(List<T> l, String a) {
}
@@ -7,5 +7,5 @@ import lombok.Builder;
import lombok.Singular;
@Builder
record BuilderSingularOnRecord<T>(@Singular List<T> children, @Singular Collection<? extends Number> scarves, @SuppressWarnings("all") @Singular("rawList") List rawList) {
public record BuilderSingularOnRecord<T>(@Singular List<T> children, @Singular Collection<? extends Number> scarves, @SuppressWarnings("all") @Singular("rawList") List rawList) {
}
@@ -7,5 +7,5 @@ import lombok.RequiredArgsConstructor;
@AllArgsConstructor
@RequiredArgsConstructor
@NoArgsConstructor
record ConstructorsOnRecord(String a, String b) {
public record ConstructorsOnRecord(String a, String b) {
}
@@ -3,5 +3,5 @@
import lombok.Data;
@Data
record DataOnRecord(String a, String b) {
public record DataOnRecord(String a, String b) {
}
@@ -3,5 +3,5 @@
import lombok.EqualsAndHashCode;
@EqualsAndHashCode
record EqualsAndHashCodeOnRecord(String a, String b) {
public record EqualsAndHashCodeOnRecord(String a, String b) {
}
@@ -1,5 +1,5 @@
// version 14:
@lombok.experimental.FieldDefaults(makeFinal = true)
record FieldDefaultsOnRecord(String a, String b) {
public record FieldDefaultsOnRecord(String a, String b) {
}
@@ -4,6 +4,6 @@ import lombok.experimental.FieldNameConstants;
import lombok.AccessLevel;
@FieldNameConstants(level = AccessLevel.PACKAGE)
record FieldNameConstantsOnRecord(String iAmADvdPlayer, int $skipMe, @FieldNameConstants.Exclude int andMe, String butPrintMePlease) {
public record FieldNameConstantsOnRecord(String iAmADvdPlayer, int $skipMe, @FieldNameConstants.Exclude int andMe, String butPrintMePlease) {
static double skipMeToo;
}
@@ -3,5 +3,5 @@
import lombok.Getter;
@Getter
record GetterOnRecord(String a, String b) {
public record GetterOnRecord(String a, String b) {
}
@@ -4,5 +4,5 @@
import lombok.extern.slf4j.Slf4j;
@Slf4j
record LoggerConfigOnRecord(String a, String b) {
public record LoggerConfigOnRecord(String a, String b) {
}
@@ -3,5 +3,5 @@
import lombok.extern.slf4j.Slf4j;
@Slf4j
record LoggerSlf4jOnRecord(String a, String b) {
public record LoggerSlf4jOnRecord(String a, String b) {
}
@@ -2,8 +2,8 @@
import lombok.NonNull;
record NonNullOnRecord(@NonNull String a, @NonNull String b) {
public NonNullOnRecord(@NonNull String b) {
public record NonNullExistingConstructorOnRecord(@NonNull String a, @NonNull String b) {
public NonNullExistingConstructorOnRecord(@NonNull String b) {
this("default", b);
}
}
@@ -2,5 +2,5 @@
import lombok.NonNull;
record NonNullOnRecord(@NonNull String a, @NonNull String b) {
public record NonNullOnRecord(@NonNull String a, @NonNull String b) {
}
@@ -2,7 +2,7 @@
import lombok.NonNull;
record NonNullOnRecord3(@NonNull String a) {
public record NonNullOnRecord3(@NonNull String a) {
public NonNullOnRecord3(String a) {
this.a = a;
}
@@ -3,5 +3,5 @@
import lombok.Setter;
@Setter
record SetterOnRecord(String a, String b) {
public record SetterOnRecord(String a, String b) {
}
@@ -2,7 +2,7 @@
import lombok.Synchronized;
record SynchronizedInRecord(String a, String b) {
public record SynchronizedInRecord(String a, String b) {
@Synchronized
public void foo() {
String foo = "bar";
@@ -3,5 +3,5 @@
import lombok.ToString;
@ToString
record ToStringOnRecord(String a, String b) {
public record ToStringOnRecord(String a, String b) {
}
@@ -3,5 +3,5 @@
import lombok.experimental.UtilityClass;
@UtilityClass
record UtilityClassOnRecord(String a, String b) {
public record UtilityClassOnRecord(String a, String b) {
}
@@ -3,5 +3,5 @@
import lombok.Value;
@Value
record ValueOnRecord(String a, String b) {
public record ValueOnRecord(String a, String b) {
}
@@ -3,5 +3,5 @@
import lombok.experimental.WithBy;
@WithBy
record WithByOnRecord(String a, String b) {
public record WithByOnRecord(String a, String b) {
}
@@ -2,5 +2,5 @@
import lombok.experimental.WithBy;
record WithByOnRecordComponent(@WithBy String a, String b) {
public record WithByOnRecordComponent(@WithBy String a, String b) {
}
@@ -3,5 +3,5 @@
import lombok.With;
@With
record WithOnRecord(String a, String b) {
public record WithOnRecord(String a, String b) {
}
@@ -2,5 +2,5 @@
import lombok.With;
record WithOnRecordComponent(@With String a, String b) {
public record WithOnRecordComponent(@With String a, String b) {
}