diff options
120 files changed, 1168 insertions, 141 deletions
diff --git a/src/core/lombok/eclipse/EclipseAST.java b/src/core/lombok/eclipse/EclipseAST.java index d53856af..2c860e14 100644 --- a/src/core/lombok/eclipse/EclipseAST.java +++ b/src/core/lombok/eclipse/EclipseAST.java @@ -21,6 +21,8 @@ */ package lombok.eclipse; +import static lombok.eclipse.handlers.EclipseHandlerUtil.*; + import java.io.File; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; @@ -34,7 +36,6 @@ import java.util.List; import lombok.Lombok; import lombok.core.AST; import lombok.core.LombokImmutableList; -import lombok.eclipse.handlers.EclipseHandlerUtil; import lombok.permit.Permit; import org.eclipse.core.resources.ResourcesPlugin; @@ -117,7 +118,7 @@ public class EclipseAST extends AST<EclipseAST, EclipseNode, ASTNode> { try { return EclipseWorkspaceBasedFileResolver.resolve(fileName); } catch (IllegalArgumentException e) { - EclipseHandlerUtil.warning("Finding 'lombok.config' file failed for '" + fileName + "'", e); + warning("Finding 'lombok.config' file failed for '" + fileName + "'", e); // String msg = e.getMessage(); // if (msg != null && msg.startsWith("Path must include project and resource name")) { // // We shouldn't throw an exception at all, but we can't reproduce this so we need help from our users to figure this out. @@ -362,7 +363,7 @@ public class EclipseAST extends AST<EclipseAST, EclipseNode, ASTNode> { case TYPE: return buildType((TypeDeclaration) node); case FIELD: - return buildField((FieldDeclaration) node); + return buildField((FieldDeclaration) node, null); case INITIALIZER: return buildInitializer((Initializer) node); case METHOD: @@ -401,16 +402,16 @@ public class EclipseAST extends AST<EclipseAST, EclipseNode, ASTNode> { private EclipseNode buildType(TypeDeclaration type) { if (setAndGetAsHandled(type)) return null; List<EclipseNode> childNodes = new ArrayList<EclipseNode>(); - childNodes.addAll(buildFields(type.fields)); + childNodes.addAll(buildFields(type.fields, getRecordFieldAnnotations(type))); childNodes.addAll(buildTypes(type.memberTypes)); childNodes.addAll(buildMethods(type.methods)); childNodes.addAll(buildAnnotations(type.annotations, false)); return putInMap(new EclipseNode(this, type, childNodes, Kind.TYPE)); } - private Collection<EclipseNode> buildFields(FieldDeclaration[] children) { + private Collection<EclipseNode> buildFields(FieldDeclaration[] children, Annotation[][] annotations) { List<EclipseNode> childNodes = new ArrayList<EclipseNode>(); - if (children != null) for (FieldDeclaration child : children) addIfNotNull(childNodes, buildField(child)); + if (children != null) for (int i = 0; i < children.length; i++) addIfNotNull(childNodes, buildField(children[i], annotations[i])); return childNodes; } @@ -420,13 +421,13 @@ public class EclipseAST extends AST<EclipseAST, EclipseNode, ASTNode> { return list; } - private EclipseNode buildField(FieldDeclaration field) { + private EclipseNode buildField(FieldDeclaration field, Annotation[] annotations) { if (field instanceof Initializer) return buildInitializer((Initializer)field); if (setAndGetAsHandled(field)) return null; List<EclipseNode> childNodes = new ArrayList<EclipseNode>(); addIfNotNull(childNodes, buildTypeUse(field.type)); addIfNotNull(childNodes, buildStatement(field.initialization)); - childNodes.addAll(buildAnnotations(field.annotations, true)); + childNodes.addAll(buildAnnotations(annotations != null ? annotations : field.annotations, true)); return putInMap(new EclipseNode(this, field, childNodes, Kind.FIELD)); } diff --git a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java index 6bfcf16e..c70e4e5c 100644 --- a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java +++ b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java @@ -124,6 +124,7 @@ import lombok.core.handlers.HandlerUtil.FieldAccess; import lombok.eclipse.Eclipse; import lombok.eclipse.EclipseAST; import lombok.eclipse.EclipseNode; +import lombok.eclipse.Java14Bits; import lombok.experimental.Accessors; import lombok.experimental.Tolerate; import lombok.permit.Permit; @@ -332,6 +333,7 @@ public class EclipseHandlerUtil { public static final Field TYPE_REFERENCE__ANNOTATIONS; public static final Class<?> INTERSECTION_BINDING1, INTERSECTION_BINDING2; public static final Field INTERSECTION_BINDING_TYPES1, INTERSECTION_BINDING_TYPES2; + public static final Field TYPE_DECLARATION_RECORD_COMPONENTS; static { STRING_LITERAL__LINE_NUMBER = getField(StringLiteral.class, "lineNumber"); ANNOTATION__MEMBER_VALUE_PAIR_NAME = getField(Annotation.class, "memberValuePairName"); @@ -340,6 +342,7 @@ public class EclipseHandlerUtil { INTERSECTION_BINDING2 = getClass("org.eclipse.jdt.internal.compiler.lookup.IntersectionCastTypeBinding"); INTERSECTION_BINDING_TYPES1 = INTERSECTION_BINDING1 == null ? null : getField(INTERSECTION_BINDING1, "intersectingTypes"); INTERSECTION_BINDING_TYPES2 = INTERSECTION_BINDING2 == null ? null : getField(INTERSECTION_BINDING2, "intersectingTypes"); + TYPE_DECLARATION_RECORD_COMPONENTS = getField(TypeDeclaration.class, "recordComponents"); } public static int reflectInt(Field f, Object o) { @@ -771,12 +774,10 @@ public class EclipseHandlerUtil { } public static boolean hasNonNullAnnotations(EclipseNode node) { - AbstractVariableDeclaration avd = (AbstractVariableDeclaration) node.get(); - if (avd.annotations == null) return false; - for (Annotation annotation : avd.annotations) { - TypeReference typeRef = annotation.type; - if (typeRef != null && typeRef.getTypeName() != null) { - for (String bn : NONNULL_ANNOTATIONS) if (typeMatches(bn, node, typeRef)) return true; + for (EclipseNode child : node.down()) { + if (child.getKind() == Kind.ANNOTATION) { + Annotation annotation = (Annotation) child.get(); + for (String bn : NONNULL_ANNOTATIONS) if (typeMatches(bn, node, annotation.type)) return true; } } return false; @@ -1888,6 +1889,31 @@ public class EclipseHandlerUtil { } /** + * Checks if there is a constructor 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) { + if ((def.bits & (ASTNode.IsDefaultConstructor | Java14Bits.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. */ @@ -2635,4 +2661,57 @@ public class EclipseHandlerUtil { setGeneratedBy(ref, source); return ref; } + + static boolean isClass(EclipseNode typeNode) { + return isClassAndDoesNotHaveFlags(typeNode, ClassFileConstants.AccInterface | ClassFileConstants.AccEnum | ClassFileConstants.AccAnnotation | Java14Bits.AccRecord); + } + + static boolean isClassOrEnum(EclipseNode typeNode) { + return isClassAndDoesNotHaveFlags(typeNode, ClassFileConstants.AccInterface | ClassFileConstants.AccAnnotation | Java14Bits.AccRecord); + } + + public static boolean isClassAndDoesNotHaveFlags(EclipseNode typeNode, long flags) { + TypeDeclaration typeDecl = null; + if (typeNode.get() instanceof TypeDeclaration) typeDecl = (TypeDeclaration) typeNode.get(); + int modifiers = typeDecl == null ? 0 : typeDecl.modifiers; + return (modifiers & flags) == 0; + } + + public static boolean isRecord(EclipseNode typeNode) { + return typeNode.getKind() == Kind.TYPE && isRecord((TypeDeclaration) typeNode.get()); + } + + public static boolean isRecord(TypeDeclaration typeDeclaration) { + return (typeDeclaration.modifiers & Java14Bits.AccRecord) != 0; + } + + public static boolean isRecordField(EclipseNode fieldNode) { + return fieldNode.getKind() == Kind.FIELD && (((FieldDeclaration) fieldNode.get()).modifiers & Java14Bits.AccRecord) != 0; + } + + public static AbstractVariableDeclaration[] getRecordComponents(TypeDeclaration typeDeclaration) { + if (!isRecord(typeDeclaration)) return null; + try { + return (AbstractVariableDeclaration[]) TYPE_DECLARATION_RECORD_COMPONENTS.get(typeDeclaration); + } catch (Exception e) { + // Ignore + } + return null; + } + + public static Annotation[][] getRecordFieldAnnotations(TypeDeclaration typeDeclaration) { + if (typeDeclaration.fields == null) return null; + Annotation[][] annotations = new Annotation[typeDeclaration.fields.length][]; + + AbstractVariableDeclaration[] recordComponents = getRecordComponents(typeDeclaration); + if (recordComponents != null) { + int j = 0; + for (int i = 0; i < typeDeclaration.fields.length; i++) { + if ((typeDeclaration.fields[i].modifiers & Java14Bits.AccRecord) != 0) { + annotations[i] = recordComponents[j++].annotations; + } + } + } + return annotations; + } } diff --git a/src/core/lombok/eclipse/handlers/HandleBuilder.java b/src/core/lombok/eclipse/handlers/HandleBuilder.java index 801fe7e7..5054703a 100755 --- a/src/core/lombok/eclipse/handlers/HandleBuilder.java +++ b/src/core/lombok/eclipse/handlers/HandleBuilder.java @@ -272,8 +272,10 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> { allFields.add(fieldNode); } - handleConstructor.generateConstructor(tdParent, AccessLevel.PACKAGE, allFields, false, null, SkipIfConstructorExists.I_AM_BUILDER, - Collections.<Annotation>emptyList(), annotationNode); + if (!isRecord(tdParent)) { + handleConstructor.generateConstructor(tdParent, AccessLevel.PACKAGE, allFields, false, null, SkipIfConstructorExists.I_AM_BUILDER, + Collections.<Annotation>emptyList(), annotationNode); + } returnType = namePlusTypeParamsToTypeReference(tdParent, td.typeParameters, p); typeParams = td.typeParameters; diff --git a/src/core/lombok/eclipse/handlers/HandleConstructor.java b/src/core/lombok/eclipse/handlers/HandleConstructor.java index 06c9ecd9..ff81b763 100755 --- a/src/core/lombok/eclipse/handlers/HandleConstructor.java +++ b/src/core/lombok/eclipse/handlers/HandleConstructor.java @@ -194,12 +194,7 @@ public class HandleConstructor { } static boolean checkLegality(EclipseNode typeNode, EclipseNode errorNode, String name) { - TypeDeclaration typeDecl = null; - if (typeNode.get() instanceof TypeDeclaration) typeDecl = (TypeDeclaration) typeNode.get(); - int modifiers = typeDecl == null ? 0 : typeDecl.modifiers; - boolean notAClass = (modifiers & (ClassFileConstants.AccInterface | ClassFileConstants.AccAnnotation)) != 0; - - if (typeDecl == null || notAClass) { + if (!isClassOrEnum(typeNode)) { errorNode.addError(name + " is only supported on a class or an enum."); return false; } diff --git a/src/core/lombok/eclipse/handlers/HandleData.java b/src/core/lombok/eclipse/handlers/HandleData.java index 4011890d..6663d7d0 100644 --- a/src/core/lombok/eclipse/handlers/HandleData.java +++ b/src/core/lombok/eclipse/handlers/HandleData.java @@ -22,6 +22,7 @@ package lombok.eclipse.handlers; import static lombok.core.handlers.HandlerUtil.*; +import static lombok.eclipse.handlers.EclipseHandlerUtil.isClass; import java.util.Collections; @@ -34,8 +35,6 @@ import lombok.eclipse.EclipseNode; import lombok.eclipse.handlers.HandleConstructor.SkipIfConstructorExists; import org.eclipse.jdt.internal.compiler.ast.Annotation; -import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; -import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; import org.mangosdk.spi.ProviderFor; /** @@ -55,13 +54,7 @@ public class HandleData extends EclipseAnnotationHandler<Data> { Data ann = annotation.getInstance(); EclipseNode typeNode = annotationNode.up(); - TypeDeclaration typeDecl = null; - if (typeNode.get() instanceof TypeDeclaration) typeDecl = (TypeDeclaration) typeNode.get(); - int modifiers = typeDecl == null ? 0 : typeDecl.modifiers; - boolean notAClass = (modifiers & - (ClassFileConstants.AccInterface | ClassFileConstants.AccAnnotation | ClassFileConstants.AccEnum)) != 0; - - if (typeDecl == null || notAClass) { + if (!isClass(typeNode)) { annotationNode.addError("@Data is only supported on a class."); return; } diff --git a/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java b/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java index 7147343e..83e6de61 100755 --- a/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java +++ b/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java @@ -137,13 +137,9 @@ public class HandleEqualsAndHashCode extends EclipseAnnotationHandler<EqualsAndH Boolean callSuper, boolean whineIfExists, FieldAccess fieldAccess, List<Annotation> onParam) { TypeDeclaration typeDecl = null; - if (typeNode.get() instanceof TypeDeclaration) typeDecl = (TypeDeclaration) typeNode.get(); - int modifiers = typeDecl == null ? 0 : typeDecl.modifiers; - boolean notAClass = (modifiers & - (ClassFileConstants.AccInterface | ClassFileConstants.AccAnnotation | ClassFileConstants.AccEnum)) != 0; - if (typeDecl == null || notAClass) { + if (!isClass(typeNode)) { errorNode.addError("@EqualsAndHashCode is only supported on a class."); return; } diff --git a/src/core/lombok/eclipse/handlers/HandleFieldDefaults.java b/src/core/lombok/eclipse/handlers/HandleFieldDefaults.java index 702713fe..4927a8fb 100644 --- a/src/core/lombok/eclipse/handlers/HandleFieldDefaults.java +++ b/src/core/lombok/eclipse/handlers/HandleFieldDefaults.java @@ -63,13 +63,7 @@ public class HandleFieldDefaults extends EclipseASTAdapter { } } - TypeDeclaration typeDecl = null; - if (typeNode.get() instanceof TypeDeclaration) typeDecl = (TypeDeclaration) typeNode.get(); - int modifiers = typeDecl == null ? 0 : typeDecl.modifiers; - boolean notAClass = (modifiers & - (ClassFileConstants.AccInterface | ClassFileConstants.AccAnnotation)) != 0; - - if (typeDecl == null || notAClass) { + if (!isClassOrEnum(typeNode)) { pos.addError("@FieldDefaults is only supported on a class or an enum."); return false; } diff --git a/src/core/lombok/eclipse/handlers/HandleGetter.java b/src/core/lombok/eclipse/handlers/HandleGetter.java index 9cd1e2a1..755311b1 100644 --- a/src/core/lombok/eclipse/handlers/HandleGetter.java +++ b/src/core/lombok/eclipse/handlers/HandleGetter.java @@ -90,13 +90,7 @@ public class HandleGetter extends EclipseAnnotationHandler<Getter> { } } - TypeDeclaration typeDecl = null; - if (typeNode.get() instanceof TypeDeclaration) typeDecl = (TypeDeclaration) typeNode.get(); - int modifiers = typeDecl == null ? 0 : typeDecl.modifiers; - boolean notAClass = (modifiers & - (ClassFileConstants.AccInterface | ClassFileConstants.AccAnnotation)) != 0; - - if (typeDecl == null || notAClass) { + if (!isClassOrEnum(typeNode)) { pos.addError("@Getter is only supported on a class, an enum, or a field."); return false; } diff --git a/src/core/lombok/eclipse/handlers/HandleLog.java b/src/core/lombok/eclipse/handlers/HandleLog.java index a0e431e5..9eae601b 100644 --- a/src/core/lombok/eclipse/handlers/HandleLog.java +++ b/src/core/lombok/eclipse/handlers/HandleLog.java @@ -85,6 +85,10 @@ public class HandleLog { annotationNode.addWarning("Field '" + logFieldName + "' already exists."); return; } + if (isRecord(owner) && !useStatic) { + annotationNode.addError("Logger fields must be static in records."); + return; + } Object valueGuess = annotation.getValueGuess("topic"); Expression loggerTopic = (Expression) annotation.getActualExpression("topic"); diff --git a/src/core/lombok/eclipse/handlers/HandleNonNull.java b/src/core/lombok/eclipse/handlers/HandleNonNull.java index 903d098b..8dc4f4f7 100644 --- a/src/core/lombok/eclipse/handlers/HandleNonNull.java +++ b/src/core/lombok/eclipse/handlers/HandleNonNull.java @@ -26,6 +26,7 @@ import static lombok.eclipse.Eclipse.isPrimitive; import static lombok.eclipse.handlers.EclipseHandlerUtil.*; import java.util.Arrays; +import java.util.Collections; import org.eclipse.jdt.internal.compiler.ast.ASTNode; import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration; @@ -48,17 +49,18 @@ import org.eclipse.jdt.internal.compiler.ast.TryStatement; import org.eclipse.jdt.internal.compiler.ast.TypeReference; import org.mangosdk.spi.ProviderFor; +import lombok.AccessLevel; import lombok.ConfigurationKeys; import lombok.NonNull; import lombok.core.AST.Kind; import lombok.core.AnnotationValues; import lombok.core.HandlerPriority; -import lombok.eclipse.DeferUntilPostDiet; import lombok.eclipse.EclipseAST; import lombok.eclipse.EclipseAnnotationHandler; +import lombok.eclipse.EclipseAugments; import lombok.eclipse.EclipseNode; +import lombok.eclipse.handlers.HandleConstructor.SkipIfConstructorExists; -@DeferUntilPostDiet @ProviderFor(EclipseAnnotationHandler.class) @HandlerPriority(value = 512) // 2^9; onParameter=@__(@NonNull) has to run first. public class HandleNonNull extends EclipseAnnotationHandler<NonNull> { @@ -66,6 +68,7 @@ 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()) { @@ -81,6 +84,17 @@ public class HandleNonNull extends EclipseAnnotationHandler<NonNull> { } @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); + } + EclipseAugments.ASTNode_handled.clear(ast); + return; + } + handle0(ast, annotationNode, false); } diff --git a/src/core/lombok/eclipse/handlers/HandleSetter.java b/src/core/lombok/eclipse/handlers/HandleSetter.java index cb2ca3bf..9ebbde6d 100644 --- a/src/core/lombok/eclipse/handlers/HandleSetter.java +++ b/src/core/lombok/eclipse/handlers/HandleSetter.java @@ -71,13 +71,7 @@ public class HandleSetter extends EclipseAnnotationHandler<Setter> { } } - TypeDeclaration typeDecl = null; - if (typeNode.get() instanceof TypeDeclaration) typeDecl = (TypeDeclaration) typeNode.get(); - int modifiers = typeDecl == null ? 0 : typeDecl.modifiers; - boolean notAClass = (modifiers & - (ClassFileConstants.AccInterface | ClassFileConstants.AccAnnotation | ClassFileConstants.AccEnum)) != 0; - - if (typeDecl == null || notAClass) { + if (!isClass(typeNode)) { pos.addError("@Setter is only supported on a class or a field."); return false; } diff --git a/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java b/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java index b1e7c419..89c27fe3 100644 --- a/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java +++ b/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java @@ -156,7 +156,7 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> { boolean addCleaning = false; - if (!(tdParent.get() instanceof TypeDeclaration)) { + if (!isClass(tdParent)) { annotationNode.addError("@SuperBuilder is only supported on types."); return; } diff --git a/src/core/lombok/eclipse/handlers/HandleSynchronized.java b/src/core/lombok/eclipse/handlers/HandleSynchronized.java index 08d00d91..37d6755c 100644 --- a/src/core/lombok/eclipse/handlers/HandleSynchronized.java +++ b/src/core/lombok/eclipse/handlers/HandleSynchronized.java @@ -148,6 +148,12 @@ public class HandleSynchronized extends EclipseAnnotationHandler<Synchronized> { return; } + EclipseNode typeNode = upToTypeNode(annotationNode); + if (!isClassOrEnum(typeNode)) { + annotationNode.addError("@Synchronized is legal only on methods in classes and enums."); + return; + } + boolean[] isStatic = { method.isStatic() }; char[] lockName = createLockField(annotation, annotationNode, isStatic, true); if (lockName == null) return; @@ -163,7 +169,6 @@ public class HandleSynchronized extends EclipseAnnotationHandler<Synchronized> { Expression lockVariable; if (isStatic[0]) { - EclipseNode typeNode = upToTypeNode(annotationNode); char[][] n = getQualifiedInnerName(typeNode, lockName); long[] ps = new long[n.length]; Arrays.fill(ps, pos); diff --git a/src/core/lombok/eclipse/handlers/HandleToString.java b/src/core/lombok/eclipse/handlers/HandleToString.java index a6bcb24f..9b58474c 100644 --- a/src/core/lombok/eclipse/handlers/HandleToString.java +++ b/src/core/lombok/eclipse/handlers/HandleToString.java @@ -50,7 +50,6 @@ import org.eclipse.jdt.internal.compiler.ast.SuperReference; import org.eclipse.jdt.internal.compiler.ast.ThisReference; 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 org.eclipse.jdt.internal.compiler.lookup.TypeConstants; import org.mangosdk.spi.ProviderFor; @@ -116,14 +115,7 @@ public class HandleToString extends EclipseAnnotationHandler<ToString> { public void generateToString(EclipseNode typeNode, EclipseNode errorNode, List<Included<EclipseNode, ToString.Include>> members, boolean includeFieldNames, Boolean callSuper, boolean whineIfExists, FieldAccess fieldAccess) { - TypeDeclaration typeDecl = null; - - if (typeNode.get() instanceof TypeDeclaration) typeDecl = (TypeDeclaration) typeNode.get(); - int modifiers = typeDecl == null ? 0 : typeDecl.modifiers; - boolean notAClass = (modifiers & - (ClassFileConstants.AccInterface | ClassFileConstants.AccAnnotation)) != 0; - - if (typeDecl == null || notAClass) { + if (!isClassOrEnum(typeNode)) { errorNode.addError("@ToString is only supported on a class or enum."); return; } diff --git a/src/core/lombok/eclipse/handlers/HandleUtilityClass.java b/src/core/lombok/eclipse/handlers/HandleUtilityClass.java index 2349f839..338aab0d 100644 --- a/src/core/lombok/eclipse/handlers/HandleUtilityClass.java +++ b/src/core/lombok/eclipse/handlers/HandleUtilityClass.java @@ -70,13 +70,8 @@ public class HandleUtilityClass extends EclipseAnnotationHandler<UtilityClass> { } private static boolean checkLegality(EclipseNode typeNode, EclipseNode errorNode) { - TypeDeclaration typeDecl = null; - if (typeNode.get() instanceof TypeDeclaration) typeDecl = (TypeDeclaration) typeNode.get(); - int modifiers = typeDecl == null ? 0 : typeDecl.modifiers; - boolean notAClass = (modifiers & (ClassFileConstants.AccInterface | ClassFileConstants.AccAnnotation | ClassFileConstants.AccEnum)) != 0; - - if (typeDecl == null || notAClass) { - errorNode.addError("@UtilityClass is only supported on a class (can't be an interface, enum, or annotation)."); + if (!isClass(typeNode)) { + errorNode.addError("@UtilityClass is only supported on a class (can't be an interface, enum, annotation, or record)."); return false; } diff --git a/src/core/lombok/eclipse/handlers/HandleValue.java b/src/core/lombok/eclipse/handlers/HandleValue.java index 2e0338a8..abea5603 100644 --- a/src/core/lombok/eclipse/handlers/HandleValue.java +++ b/src/core/lombok/eclipse/handlers/HandleValue.java @@ -61,11 +61,8 @@ public class HandleValue extends EclipseAnnotationHandler<Value> { TypeDeclaration typeDecl = null; if (typeNode.get() instanceof TypeDeclaration) typeDecl = (TypeDeclaration) typeNode.get(); - int modifiers = typeDecl == null ? 0 : typeDecl.modifiers; - boolean notAClass = (modifiers & - (ClassFileConstants.AccInterface | ClassFileConstants.AccAnnotation | ClassFileConstants.AccEnum)) != 0; - if (typeDecl == null || notAClass) { + if (!isClass(typeNode)) { annotationNode.addError("@Value is only supported on a class."); return; } diff --git a/src/core/lombok/eclipse/handlers/HandleWithBy.java b/src/core/lombok/eclipse/handlers/HandleWithBy.java index 5f229aaf..40e2d524 100644 --- a/src/core/lombok/eclipse/handlers/HandleWithBy.java +++ b/src/core/lombok/eclipse/handlers/HandleWithBy.java @@ -29,7 +29,9 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.LinkedHashSet; import java.util.List; +import java.util.Set; import org.eclipse.jdt.internal.compiler.ast.ASTNode; import org.eclipse.jdt.internal.compiler.ast.AllocationExpression; @@ -136,7 +138,10 @@ public class HandleWithBy extends EclipseAnnotationHandler<WithBy> { switch (node.getKind()) { case FIELD: - createWithByForFields(level, annotationNode.upFromAnnotationToFields(), annotationNode, true, onMethod); + Set<EclipseNode> fields = new LinkedHashSet<EclipseNode>(); + fields.add(node); + fields.addAll(annotationNode.upFromAnnotationToFields()); + createWithByForFields(level, fields, annotationNode, true, onMethod); break; case TYPE: if (!onMethod.isEmpty()) { diff --git a/src/core/lombok/javac/handlers/HandleBuilder.java b/src/core/lombok/javac/handlers/HandleBuilder.java index 7e87ce11..f9675813 100644 --- a/src/core/lombok/javac/handlers/HandleBuilder.java +++ b/src/core/lombok/javac/handlers/HandleBuilder.java @@ -223,7 +223,9 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> { allFields.append(fieldNode); } - handleConstructor.generateConstructor(tdParent, AccessLevel.PACKAGE, List.<JCAnnotation>nil(), allFields.toList(), false, null, SkipIfConstructorExists.I_AM_BUILDER, annotationNode); + if (!isRecord(tdParent)) { + handleConstructor.generateConstructor(tdParent, AccessLevel.PACKAGE, List.<JCAnnotation>nil(), allFields.toList(), false, null, SkipIfConstructorExists.I_AM_BUILDER, annotationNode); + } returnType = namePlusTypeParamsToTypeReference(tdParent.getTreeMaker(), tdParent, td.typarams); typeParams = td.typarams; diff --git a/src/core/lombok/javac/handlers/HandleConstructor.java b/src/core/lombok/javac/handlers/HandleConstructor.java index 2a683767..54a9f821 100644 --- a/src/core/lombok/javac/handlers/HandleConstructor.java +++ b/src/core/lombok/javac/handlers/HandleConstructor.java @@ -184,12 +184,7 @@ public class HandleConstructor { } public static boolean checkLegality(JavacNode typeNode, JavacNode errorNode, String name) { - JCClassDecl typeDecl = null; - if (typeNode.get() instanceof JCClassDecl) typeDecl = (JCClassDecl) typeNode.get(); - long modifiers = typeDecl == null ? 0 : typeDecl.mods.flags; - boolean notAClass = (modifiers & (Flags.INTERFACE | Flags.ANNOTATION)) != 0; - - if (typeDecl == null || notAClass) { + if (!isClassOrEnum(typeNode)) { errorNode.addError(name + " is only supported on a class or an enum."); return false; } diff --git a/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java b/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java index d490738e..e35deb5b 100644 --- a/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java +++ b/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java @@ -113,13 +113,7 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas public void generateMethods(JavacNode typeNode, JavacNode source, java.util.List<Included<JavacNode, EqualsAndHashCode.Include>> members, Boolean callSuper, boolean whineIfExists, FieldAccess fieldAccess, List<JCAnnotation> onParam) { - boolean notAClass = true; - if (typeNode.get() instanceof JCClassDecl) { - long flags = ((JCClassDecl) typeNode.get()).mods.flags; - notAClass = (flags & (Flags.INTERFACE | Flags.ANNOTATION | Flags.ENUM)) != 0; - } - - if (notAClass) { + if (!isClass(typeNode)) { source.addError("@EqualsAndHashCode is only supported on a class."); return; } diff --git a/src/core/lombok/javac/handlers/HandleFieldDefaults.java b/src/core/lombok/javac/handlers/HandleFieldDefaults.java index aa381c0d..c974bdb9 100644 --- a/src/core/lombok/javac/handlers/HandleFieldDefaults.java +++ b/src/core/lombok/javac/handlers/HandleFieldDefaults.java @@ -57,12 +57,7 @@ public class HandleFieldDefaults extends JavacASTAdapter { } } - JCClassDecl typeDecl = null; - if (typeNode.get() instanceof JCClassDecl) typeDecl = (JCClassDecl) typeNode.get(); - long modifiers = typeDecl == null ? 0 : typeDecl.mods.flags; - boolean notAClass = (modifiers & (Flags.INTERFACE | Flags.ANNOTATION)) != 0; - - if (typeDecl == null || notAClass) { + if (!isClassOrEnum(typeNode)) { errorNode.addError("@FieldDefaults is only supported on a class or an enum."); return false; } diff --git a/src/core/lombok/javac/handlers/HandleGetter.java b/src/core/lombok/javac/handlers/HandleGetter.java index 110941d6..1b4d404b 100644 --- a/src/core/lombok/javac/handlers/HandleGetter.java +++ b/src/core/lombok/javac/handlers/HandleGetter.java @@ -52,7 +52,6 @@ import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.JCTree.JCAnnotation; import com.sun.tools.javac.tree.JCTree.JCBinary; import com.sun.tools.javac.tree.JCTree.JCBlock; -import com.sun.tools.javac.tree.JCTree.JCClassDecl; import com.sun.tools.javac.tree.JCTree.JCExpression; import com.sun.tools.javac.tree.JCTree.JCExpressionStatement; import com.sun.tools.javac.tree.JCTree.JCIf; @@ -81,12 +80,7 @@ public class HandleGetter extends JavacAnnotationHandler<Getter> { } } - JCClassDecl typeDecl = null; - if (typeNode.get() instanceof JCClassDecl) typeDecl = (JCClassDecl) typeNode.get(); - long modifiers = typeDecl == null ? 0 : typeDecl.mods.flags; - boolean notAClass = (modifiers & (Flags.INTERFACE | Flags.ANNOTATION)) != 0; - - if (typeDecl == null || notAClass) { + if (!isClassOrEnum(typeNode)) { errorNode.addError("@Getter is only supported on a class, an enum, or a field."); return; } diff --git a/src/core/lombok/javac/handlers/HandleLog.java b/src/core/lombok/javac/handlers/HandleLog.java index 3173b3ba..1ff10ad1 100644 --- a/src/core/lombok/javac/handlers/HandleLog.java +++ b/src/core/lombok/javac/handlers/HandleLog.java @@ -75,6 +75,10 @@ public class HandleLog { annotationNode.addWarning("Field '" + logFieldName + "' already exists."); return; } + if (isRecord(typeNode) && !useStatic) { + annotationNode.addError("Logger fields must be static in records."); + return; + } Object valueGuess = annotation.getValueGuess("topic"); JCExpression loggerTopic = (JCExpression) annotation.getActualExpression("topic"); @@ -120,10 +124,15 @@ public class HandleLog { maker.Modifiers(Flags.PRIVATE | Flags.FINAL | (useStatic ? Flags.STATIC : 0)), typeNode.toName(logFieldName), loggerType, factoryMethodCall), source, typeNode.getContext()); - injectFieldAndMarkGenerated(typeNode, fieldDecl); + // This is a workaround for https://bugs.openjdk.java.net/browse/JDK-8243057 + if (isRecord(typeNode)) { + injectField(typeNode, fieldDecl); + } else { + injectFieldAndMarkGenerated(typeNode, fieldDecl); + } return true; } - + private static JCExpression[] createFactoryParameters(JavacNode typeNode, JCFieldAccess loggingType, java.util.List<LogFactoryParameter> parameters, JCExpression loggerTopic) { JCExpression[] expressions = new JCExpression[parameters.size()]; JavacTreeMaker maker = typeNode.getTreeMaker(); diff --git a/src/core/lombok/javac/handlers/HandleNonNull.java b/src/core/lombok/javac/handlers/HandleNonNull.java index 079d5b04..6b6b7efa 100644 --- a/src/core/lombok/javac/handlers/HandleNonNull.java +++ b/src/core/lombok/javac/handlers/HandleNonNull.java @@ -51,17 +51,23 @@ import com.sun.tools.javac.tree.JCTree.JCVariableDecl; import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.Name; +import lombok.AccessLevel; import lombok.ConfigurationKeys; import lombok.NonNull; import lombok.core.AST.Kind; import lombok.core.AnnotationValues; import lombok.core.HandlerPriority; + +import lombok.javac.Java14Flags; import lombok.javac.JavacAnnotationHandler; import lombok.javac.JavacNode; +import lombok.javac.handlers.HandleConstructor.SkipIfConstructorExists; @ProviderFor(JavacAnnotationHandler.class) @HandlerPriority(value = 512) // 2^9; onParameter=@__(@NonNull) has to run first. public class HandleNonNull extends JavacAnnotationHandler<NonNull> { + private HandleConstructor handleConstructor = new HandleConstructor(); + @Override public void handle(AnnotationValues<NonNull> annotation, JCAnnotation ast, JavacNode annotationNode) { handleFlagUsage(annotationNode, ConfigurationKeys.NON_NULL_FLAG_USAGE, "@NonNull"); @@ -119,6 +125,15 @@ public class HandleNonNull extends JavacAnnotationHandler<NonNull> { return; } + JavacNode typeNode = upToTypeNode(annotationNode); + + if ((declaration.mods.flags & Java14Flags.RECORD) != 0) { + if (!lombokConstructorExists(typeNode)) { + handleConstructor.generateAllArgsConstructor(typeNode, AccessLevel.PUBLIC, null, SkipIfConstructorExists.NO, annotationNode); + } + return; + } + List<JCStatement> statements = declaration.body.stats; String expectedName = paramNode.getName(); diff --git a/src/core/lombok/javac/handlers/HandleSetter.java b/src/core/lombok/javac/handlers/HandleSetter.java index 82c95719..b51574b7 100644 --- a/src/core/lombok/javac/handlers/HandleSetter.java +++ b/src/core/lombok/javac/handlers/HandleSetter.java @@ -70,12 +70,7 @@ public class HandleSetter extends JavacAnnotationHandler<Setter> { } } - JCClassDecl typeDecl = null; - if (typeNode.get() instanceof JCClassDecl) typeDecl = (JCClassDecl) typeNode.get(); - long modifiers = typeDecl == null ? 0 : typeDecl.mods.flags; - boolean notAClass = (modifiers & (Flags.INTERFACE | Flags.ANNOTATION | Flags.ENUM)) != 0; - - if (typeDecl == null || notAClass) { + if (!isClass(typeNode)) { errorNode.addError("@Setter is only supported on a class or a field."); return; } diff --git a/src/core/lombok/javac/handlers/HandleSuperBuilder.java b/src/core/lombok/javac/handlers/HandleSuperBuilder.java index f6bf9e1f..be6ddae2 100644 --- a/src/core/lombok/javac/handlers/HandleSuperBuilder.java +++ b/src/core/lombok/javac/handlers/HandleSuperBuilder.java @@ -128,7 +128,7 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> { boolean addCleaning = false; - if (!(tdParent.get() instanceof JCClassDecl)) { + if (!isClass(tdParent)) { annotationNode.addError("@SuperBuilder is only supported on types."); return; } diff --git a/src/core/lombok/javac/handlers/HandleSynchronized.java b/src/core/lombok/javac/handlers/HandleSynchronized.java index b6f1e47f..85dc7e80 100644 --- a/src/core/lombok/javac/handlers/HandleSynchronized.java +++ b/src/core/lombok/javac/handlers/HandleSynchronized.java @@ -78,6 +78,12 @@ public class HandleSynchronized extends JavacAnnotationHandler<Synchronized> { return; } + JavacNode typeNode = upToTypeNode(annotationNode); + if (!isClassOrEnum(typeNode)) { + annotationNode.addError("@Synchronized is legal only on methods in classes and enums."); + return; + } + boolean[] isStatic = new boolean[] {(method.mods.flags & Flags.STATIC) != 0}; String lockName = annotation.getInstance().value(); boolean autoMake = false; @@ -89,8 +95,6 @@ public class HandleSynchronized extends JavacAnnotationHandler<Synchronized> { JavacTreeMaker maker = methodNode.getTreeMaker().at(ast.pos); Context context = methodNode.getContext(); - JavacNode typeNode = upToTypeNode(annotationNode); - MemberExistsResult exists = MemberExistsResult.NOT_EXISTS; if (typeNode != null && typeNode.get() instanceof JCClassDecl) { diff --git a/src/core/lombok/javac/handlers/HandleToString.java b/src/core/lombok/javac/handlers/HandleToString.java index 0a950f7c..ff0016e4 100644 --- a/src/core/lombok/javac/handlers/HandleToString.java +++ b/src/core/lombok/javac/handlers/HandleToString.java @@ -107,13 +107,7 @@ public class HandleToString extends JavacAnnotationHandler<ToString> { public void generateToString(JavacNode typeNode, JavacNode source, java.util.List<Included<JavacNode, ToString.Include>> members, boolean includeFieldNames, Boolean callSuper, boolean whineIfExists, FieldAccess fieldAccess) { - boolean notAClass = true; - if (typeNode.get() instanceof JCClassDecl) { - long flags = ((JCClassDecl) typeNode.get()).mods.flags; - notAClass = (flags & (Flags.INTERFACE | Flags.ANNOTATION)) != 0; - } - - if (notAClass) { + if (!isClassOrEnum(typeNode)) { source.addError("@ToString is only supported on a class or enum."); return; } diff --git a/src/core/lombok/javac/handlers/HandleUtilityClass.java b/src/core/lombok/javac/handlers/HandleUtilityClass.java index 5d651689..9ff33684 100644 --- a/src/core/lombok/javac/handlers/HandleUtilityClass.java +++ b/src/core/lombok/javac/handlers/HandleUtilityClass.java @@ -68,13 +68,8 @@ public class HandleUtilityClass extends JavacAnnotationHandler<UtilityClass> { } private static boolean checkLegality(JavacNode typeNode, JavacNode errorNode) { - JCClassDecl typeDecl = null; - if (typeNode.get() instanceof JCClassDecl) typeDecl = (JCClassDecl) typeNode.get(); - long modifiers = typeDecl == null ? 0 : typeDecl.mods.flags; - boolean notAClass = (modifiers & (Flags.INTERFACE | Flags.ANNOTATION | Flags.ENUM)) != 0; - - if (typeDecl == null || notAClass) { - errorNode.addError("@UtilityClass is only supported on a class (can't be an interface, enum, or annotation)."); + if (!isClass(typeNode)) { + errorNode.addError("@UtilityClass is only supported on a class (can't be an interface, enum, annotation, or record)."); return false; } diff --git a/src/core/lombok/javac/handlers/JavacHandlerUtil.java b/src/core/lombok/javac/handlers/JavacHandlerUtil.java index efc4bf61..cd4bc70a 100644 --- a/src/core/lombok/javac/handlers/JavacHandlerUtil.java +++ b/src/core/lombok/javac/handlers/JavacHandlerUtil.java @@ -103,6 +103,7 @@ import lombok.core.handlers.HandlerUtil.FieldAccess; import lombok.delombok.LombokOptionsFactory; import lombok.experimental.Accessors; import lombok.experimental.Tolerate; +import lombok.javac.Java14Flags; import lombok.javac.Javac; import lombok.javac.JavacNode; import lombok.javac.JavacTreeMaker; @@ -814,6 +815,32 @@ public class JavacHandlerUtil { return MemberExistsResult.NOT_EXISTS; } + /** + * Checks if there is a constructor generated by lombok. + * + * @param node Any node that represents the Type (JCClassDecl) to look in, or any child node thereof. + */ + public static boolean lombokConstructorExists(JavacNode node) { + node = upToTypeNode(node); + + if (node != null && node.get() instanceof JCClassDecl) { + for (JCTree def : ((JCClassDecl)node.get()).defs) { + if (def instanceof JCMethodDecl) { + JCMethodDecl md = (JCMethodDecl) def; + if (md.name.contentEquals("<init>")) { + if ((md.mods.flags & Flags.GENERATEDCONSTR) != 0) continue; + if (isTolerate(node, md)) continue; + if (getGeneratedBy(def) != null) { + return true; + } + } + } + } + } + + return false; + } + public static boolean isConstructorCall(final JCStatement statement) { if (!(statement instanceof JCExpressionStatement)) return false; JCExpression expr = ((JCExpressionStatement) statement).expr; @@ -1900,14 +1927,14 @@ public class JavacHandlerUtil { } static boolean isClass(JavacNode typeNode) { - return isClassAndDoesNotHaveFlags(typeNode, Flags.INTERFACE | Flags.ENUM | Flags.ANNOTATION); + return isClassAndDoesNotHaveFlags(typeNode, Flags.INTERFACE | Flags.ENUM | Flags.ANNOTATION | Java14Flags.RECORD); } static boolean isClassOrEnum(JavacNode typeNode) { - return isClassAndDoesNotHaveFlags(typeNode, Flags.INTERFACE | Flags.ANNOTATION); + return isClassAndDoesNotHaveFlags(typeNode, Flags.INTERFACE | Flags.ANNOTATION | Java14Flags.RECORD); } - public static boolean isClassAndDoesNotHaveFlags(JavacNode typeNode, int flags) { + public static boolean isClassAndDoesNotHaveFlags(JavacNode typeNode, long flags) { JCClassDecl typeDecl = null; if (typeNode.get() instanceof JCClassDecl) typeDecl = (JCClassDecl)typeNode.get(); else return false; @@ -2260,4 +2287,8 @@ public class JavacHandlerUtil { arg.mods.annotations = arg.mods.annotations == null ? List.of(m) : arg.mods.annotations.prepend(m); } } + + public static boolean isRecord(JavacNode typeNode) { + return typeNode.getKind() == Kind.TYPE && (((JCClassDecl) typeNode.get()).mods.flags & Java14Flags.RECORD) != 0; + } } diff --git a/src/delombok/lombok/delombok/PrettyPrinter.java b/src/delombok/lombok/delombok/PrettyPrinter.java index 54fa4ebf..6682b5a3 100644 --- a/src/delombok/lombok/delombok/PrettyPrinter.java +++ b/src/delombok/lombok/delombok/PrettyPrinter.java @@ -97,6 +97,7 @@ import lombok.javac.PackageName; import lombok.permit.Permit; import lombok.javac.CommentInfo.EndConnection; import lombok.javac.CommentInfo.StartConnection; +import lombok.javac.Java14Flags; import lombok.javac.JavacTreeMaker.TreeTag; import lombok.javac.JavacTreeMaker.TypeTag; @@ -516,10 +517,12 @@ public class PrettyPrinter extends JCTree.Visitor { boolean isInterface = (tree.mods.flags & INTERFACE) != 0; boolean isAnnotationInterface = isInterface && (tree.mods.flags & ANNOTATION) != 0; boolean isEnum = (tree.mods.flags & ENUM) != 0; + boolean isRecord = (tree.mods.flags & Java14Flags.RECORD) != 0; if (isAnnotationInterface) print("@interface "); else if (isInterface) print("interface "); else if (isEnum) print("enum "); + else if (isRecord) print("record "); else print("class "); print(tree.name); @@ -542,6 +545,10 @@ public class PrettyPrinter extends JCTree.Visitor { print(tree.implementing, ", "); } + if (isRecord) { + printRecordConstructor(tree.defs); + } + println(" {"); indent++; printClassMembers(tree.defs, isEnum, isInterface); @@ -551,6 +558,23 @@ public class PrettyPrinter extends JCTree.Visitor { currentTypeName = prevTypeName; } + private void printRecordConstructor(List<JCTree> members) { + boolean first = true; + print("("); + for (JCTree member : members) { + if (member instanceof JCVariableDecl) { + JCVariableDecl variableDecl = (JCVariableDecl) member; + if ((variableDecl.mods.flags & Java14Flags.GENERATED_MEMBER) != 0) { + if (!first) print(", "); + first = false; + printAnnotations(variableDecl.mods.annotations, false); + printVarDef0(variableDecl); + } + } + } + print(")"); + } + private void printClassMembers(List<JCTree> members, boolean isEnum, boolean isInterface) { Class<?> prefType = null; int typeOfPrevEnumMember = isEnum ? 3 : 0; // 1 = normal, 2 = with body, 3 = no enum field yet. @@ -580,6 +604,7 @@ public class PrettyPrinter extends JCTree.Visitor { JCTree init = ((JCVariableDecl) member).init; typeOfPrevEnumMember = init instanceof JCNewClass && ((JCNewClass) init).def != null ? 2 : 1; } else if (member instanceof JCVariableDecl) { + if ((((JCVariableDecl) member).mods.flags & Java14Flags.GENERATED_MEMBER) != 0) continue; if (prefType != null && prefType != JCVariableDecl.class) println(); if (isInterface) flagMod = -1L & ~(PUBLIC | STATIC | FINAL); print(member); diff --git a/src/utils/lombok/eclipse/Eclipse.java b/src/utils/lombok/eclipse/Eclipse.java index 31979955..cda75da5 100644 --- a/src/utils/lombok/eclipse/Eclipse.java +++ b/src/utils/lombok/eclipse/Eclipse.java @@ -239,8 +239,17 @@ public class Eclipse { for (Field f : CompilerOptions.class.getDeclaredFields()) { try { - if (f.getName().startsWith("VERSION_1_")) { - ecjCompilerVersionCached = Math.max(ecjCompilerVersionCached, Integer.parseInt(f.getName().substring("VERSION_1_".length()))); + if (f.getName().startsWith("VERSION_")) { + String version = f.getName().substring("VERSION_".length()); + Integer versionNumber = null; + if (version.startsWith("1_")) { + versionNumber = Integer.parseInt(version.substring("1_".length())); + } else if (version.length() <= 2) { + versionNumber = Integer.parseInt(version); + } + if (versionNumber != null) { + ecjCompilerVersionCached = Math.max(ecjCompilerVersionCached, versionNumber); + } } } catch (Exception ignore) {} } diff --git a/src/utils/lombok/eclipse/Java14Bits.java b/src/utils/lombok/eclipse/Java14Bits.java new file mode 100644 index 00000000..c7e00c39 --- /dev/null +++ b/src/utils/lombok/eclipse/Java14Bits.java @@ -0,0 +1,11 @@ +package lombok.eclipse; + +import org.eclipse.jdt.internal.compiler.ast.ASTNode; + +public class Java14Bits { + private Java14Bits() { } + + public static final int AccRecord = ASTNode.Bit25; + public static final int IsCanonicalConstructor = ASTNode.Bit10; // record declaration + public static final int IsImplicit = ASTNode.Bit11; // record declaration / generated statements in compact constructor +} diff --git a/src/utils/lombok/javac/Java14Flags.java b/src/utils/lombok/javac/Java14Flags.java new file mode 100644 index 00000000..0d565dca --- /dev/null +++ b/src/utils/lombok/javac/Java14Flags.java @@ -0,0 +1,26 @@ +package lombok.javac; + +public class Java14Flags { + private Java14Flags() { } + + /** + * Flag to indicate that a class is a record. The flag is also used to mark fields that are + * part of the state vector of a record and to mark the canonical constructor + */ + public static final long RECORD = 1L<<61; // ClassSymbols, MethodSymbols and VarSymbols + + /** + * Flag to mark a record constructor as a compact one + */ + public static final long COMPACT_RECORD_CONSTRUCTOR = 1L<<51; // MethodSymbols only + + /** + * Flag to mark a record field that was not initialized in the compact constructor + */ + public static final long UNINITIALIZED_FIELD= 1L<<51; // VarSymbols only + + /** Flag is set for compiler-generated record members, it could be appplied to + * accessors and fields + */ + public static final int GENERATED_MEMBER = 1<<24; // MethodSymbols and VarSymbols +} diff --git a/test/core/src/lombok/RunTestsViaEcj.java b/test/core/src/lombok/RunTestsViaEcj.java index 739d6316..7f4c2a0f 100644 --- a/test/core/src/lombok/RunTestsViaEcj.java +++ b/test/core/src/lombok/RunTestsViaEcj.java @@ -77,6 +77,8 @@ public class RunTestsViaEcj extends AbstractRunTests { warnings.put(CompilerOptions.OPTION_ReportUnusedLabel, "ignore"); warnings.put(CompilerOptions.OPTION_ReportUnusedImport, "ignore"); warnings.put(CompilerOptions.OPTION_ReportUnusedPrivateMember, "ignore"); + warnings.put("org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures", "enabled"); + warnings.put("org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures", "ignore"); int ecjVersion = Eclipse.getEcjCompilerVersion(); warnings.put(CompilerOptions.OPTION_Source, (ecjVersion < 9 ? "1." : "") + ecjVersion); options.set(warnings); diff --git a/test/transform/resource/after-delombok/BuilderSimpleOnRecord.java b/test/transform/resource/after-delombok/BuilderSimpleOnRecord.java new file mode 100644 index 00000000..03aca3aa --- /dev/null +++ b/test/transform/resource/after-delombok/BuilderSimpleOnRecord.java @@ -0,0 +1,43 @@ +import java.util.List; + +record BuilderSimpleOnRecord<T>(List<T> l, String a) { + @java.lang.SuppressWarnings("all") + protected static class BuilderSimpleOnRecordBuilder<T> { + @java.lang.SuppressWarnings("all") + private List<T> l; + @java.lang.SuppressWarnings("all") + private String a; + + @java.lang.SuppressWarnings("all") + BuilderSimpleOnRecordBuilder() { + } + + @java.lang.SuppressWarnings("all") + public BuilderSimpleOnRecord.BuilderSimpleOnRecordBuilder<T> l(final List<T> l) { + this.l = l; + return this; + } + + @java.lang.SuppressWarnings("all") + public BuilderSimpleOnRecord.BuilderSimpleOnRecordBuilder<T> a(final String a) { + this.a = a; + return this; + } + + @java.lang.SuppressWarnings("all") + public BuilderSimpleOnRecord<T> build() { + return new BuilderSimpleOnRecord<T>(this.l, this.a); + } + + @java.lang.Override + @java.lang.SuppressWarnings("all") + public java.lang.String toString() { + return "BuilderSimpleOnRecord.BuilderSimpleOnRecordBuilder(l=" + this.l + ", a=" + this.a + ")"; + } + } + + @java.lang.SuppressWarnings("all") + protected static <T> BuilderSimpleOnRecord.BuilderSimpleOnRecordBuilder<T> builder() { + return new BuilderSimpleOnRecord.BuilderSimpleOnRecordBuilder<T>(); + } +} diff --git a/test/transform/resource/after-delombok/BuilderSingularOnRecord.java b/test/transform/resource/after-delombok/BuilderSingularOnRecord.java new file mode 100644 index 00000000..32b37865 --- /dev/null +++ b/test/transform/resource/after-delombok/BuilderSingularOnRecord.java @@ -0,0 +1,136 @@ +import java.util.Collection; +import java.util.List; + +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") + private java.util.ArrayList<T> children; + @java.lang.SuppressWarnings("all") + private java.util.ArrayList<Number> scarves; + @java.lang.SuppressWarnings("all") + private java.util.ArrayList<java.lang.Object> rawList; + + @java.lang.SuppressWarnings("all") + BuilderSingularOnRecordBuilder() { + } + + @java.lang.SuppressWarnings("all") + public BuilderSingularOnRecord.BuilderSingularOnRecordBuilder<T> child(final T child) { + if (this.children == null) this.children = new java.util.ArrayList<T>(); + this.children.add(child); + return this; + } + + @java.lang.SuppressWarnings("all") + public BuilderSingularOnRecord.BuilderSingularOnRecordBuilder<T> children(final java.util.Collection<? extends T> children) { + if (children == null) { + throw new java.lang.NullPointerException("children cannot be null"); + } + if (this.children == null) this.children = new java.util.ArrayList<T>(); + this.children.addAll(children); + return this; + } + + @java.lang.SuppressWarnings("all") + public BuilderSingularOnRecord.BuilderSingularOnRecordBuilder<T> clearChildren() { + if (this.children != null) this.children.clear(); + return this; + } + + @java.lang.SuppressWarnings("all") + public BuilderSingularOnRecord.BuilderSingularOnRecordBuilder<T> scarf(final Number scarf) { + if (this.scarves == null) this.scarves = new java.util.ArrayList<Number>(); + this.scarves.add(scarf); + return this; + } + + @java.lang.SuppressWarnings("all") + public BuilderSingularOnRecord.BuilderSingularOnRecordBuilder<T> scarves(final java.util.Collection<? extends Number> scarves) { + if (scarves == null) { + throw new java.lang.NullPointerException("scarves cannot be null"); + } + if (this.scarves == null) this.scarves = new java.util.ArrayList<Number>(); + this.scarves.addAll(scarves); + return this; + } + + @java.lang.SuppressWarnings("all") + public BuilderSingularOnRecord.BuilderSingularOnRecordBuilder<T> clearScarves() { + if (this.scarves != null) this.scarves.clear(); + return this; + } + + @java.lang.SuppressWarnings("all") + public BuilderSingularOnRecord.BuilderSingularOnRecordBuilder<T> rawList(final java.lang.Object rawList) { + if (this.rawList == null) this.rawList = new java.util.ArrayList<java.lang.Object>(); + this.rawList.add(rawList); + return this; + } + + @java.lang.SuppressWarnings("all") + public BuilderSingularOnRecord.BuilderSingularOnRecordBuilder<T> rawList(final java.util.Collection<?> rawList) { + if (rawList == null) { + throw new java.lang.NullPointerException("rawList cannot be null"); + } + if (this.rawList == null) this.rawList = new java.util.ArrayList<java.lang.Object>(); + this.rawList.addAll(rawList); + return this; + } + + @java.lang.SuppressWarnings("all") + public BuilderSingularOnRecord.BuilderSingularOnRecordBuilder<T> clearRawList() { + if (this.rawList != null) this.rawList.clear(); + return this; + } + + @java.lang.SuppressWarnings("all") + public BuilderSingularOnRecord<T> build() { + java.util.List<T> children; + switch (this.children == null ? 0 : this.children.size()) { + case 0: + children = java.util.Collections.emptyList(); + break; + case 1: + children = java.util.Collections.singletonList(this.children.get(0)); + break; + default: + children = java.util.Collections.unmodifiableList(new java.util.ArrayList<T>(this.children)); + } + java.util.Collection<Number> scarves; + switch (this.scarves == null ? 0 : this.scarves.size()) { + case 0: + scarves = java.util.Collections.emptyList(); + break; + case 1: + scarves = java.util.Collections.singletonList(this.scarves.get(0)); + break; + default: + scarves = java.util.Collections.unmodifiableList(new java.util.ArrayList<Number>(this.scarves)); + } + java.util.List<java.lang.Object> rawList; + switch (this.rawList == null ? 0 : this.rawList.size()) { + case 0: + rawList = java.util.Collections.emptyList(); + break; + case 1: + rawList = java.util.Collections.singletonList(this.rawList.get(0)); + break; + default: + rawList = java.util.Collections.unmodifiableList(new java.util.ArrayList<java.lang.Object>(this.rawList)); + } + return new BuilderSingularOnRecord<T>(children, scarves, rawList); + } + + @java.lang.Override + @java.lang.SuppressWarnings("all") + public java.lang.String toString() { + return "BuilderSingularOnRecord.BuilderSingularOnRecordBuilder(children=" + this.children + ", scarves=" + this.scarves + ", rawList=" + this.rawList + ")"; + } + } + + @java.lang.SuppressWarnings("all") + public static <T> BuilderSingularOnRecord.BuilderSingularOnRecordBuilder<T> builder() { + return new BuilderSingularOnRecord.BuilderSingularOnRecordBuilder<T>(); + } +} diff --git a/test/transform/resource/after-delombok/ConstructorsOnRecord.java b/test/transform/resource/after-delombok/ConstructorsOnRecord.java new file mode 100644 index 00000000..8cef8809 --- /dev/null +++ b/test/transform/resource/after-delombok/ConstructorsOnRecord.java @@ -0,0 +1,2 @@ +record ConstructorsOnRecord(String a, String b) { +} diff --git a/test/transform/resource/after-delombok/DataOnRecord.java b/test/transform/resource/after-delombok/DataOnRecord.java new file mode 100644 index 00000000..b4384dce --- /dev/null +++ b/test/transform/resource/after-delombok/DataOnRecord.java @@ -0,0 +1,2 @@ +record DataOnRecord(String a, String b) { +} diff --git a/test/transform/resource/after-delombok/EqualsAndHashCodeOnRecord.java b/test/transform/resource/after-delombok/EqualsAndHashCodeOnRecord.java new file mode 100644 index 00000000..949cdec6 --- /dev/null +++ b/test/transform/resource/after-delombok/EqualsAndHashCodeOnRecord.java @@ -0,0 +1,2 @@ +record EqualsAndHashCodeOnRecord(String a, String b) { +} diff --git a/test/transform/resource/after-delombok/FieldDefaultsOnRecord.java b/test/transform/resource/after-delombok/FieldDefaultsOnRecord.java new file mode 100644 index 00000000..1287dcb0 --- /dev/null +++ b/test/transform/resource/after-delombok/FieldDefaultsOnRecord.java @@ -0,0 +1,2 @@ +record FieldDefaultsOnRecord(String a, String b) { +} diff --git a/test/transform/resource/after-delombok/FieldNameConstantsOnRecord.java b/test/transform/resource/after-delombok/FieldNameConstantsOnRecord.java new file mode 100644 index 00000000..2e3339fa --- /dev/null +++ b/test/transform/resource/after-delombok/FieldNameConstantsOnRecord.java @@ -0,0 +1,9 @@ +record FieldNameConstantsOnRecord(String iAmADvdPlayer, int $skipMe, int andMe, String butPrintMePlease) { + static double skipMeToo; + + @java.lang.SuppressWarnings("all") + static final class Fields { + public static final java.lang.String iAmADvdPlayer = "iAmADvdPlayer"; + public static final java.lang.String butPrintMePlease = "butPrintMePlease"; + } +} diff --git a/test/transform/resource/after-delombok/GetterOnRecord.java b/test/transform/resource/after-delombok/GetterOnRecord.java new file mode 100644 index 00000000..5090e92d --- /dev/null +++ b/test/transform/resource/after-delombok/GetterOnRecord.java @@ -0,0 +1,2 @@ +record GetterOnRecord(String a, String b) { +} diff --git a/test/transform/resource/after-delombok/LoggerConfigOnRecord.java b/test/transform/resource/after-delombok/LoggerConfigOnRecord.java new file mode 100644 index 00000000..5b43f24e --- /dev/null +++ b/test/transform/resource/after-delombok/LoggerConfigOnRecord.java @@ -0,0 +1,2 @@ +record LoggerConfigOnRecord(String a, String b) { +} diff --git a/test/transform/resource/after-delombok/LoggerSlf4jNonStaticOnRecord.java b/test/transform/resource/after-delombok/LoggerSlf4jNonStaticOnRecord.java new file mode 100644 index 00000000..e59ed6d3 --- /dev/null +++ b/test/transform/resource/after-delombok/LoggerSlf4jNonStaticOnRecord.java @@ -0,0 +1,3 @@ +record LoggerSlf4jOnRecord(String a, String b) { + private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LoggerSlf4jOnRecord.class); +} diff --git a/test/transform/resource/after-delombok/LoggerSlf4jOnRecord.java b/test/transform/resource/after-delombok/LoggerSlf4jOnRecord.java new file mode 100644 index 00000000..e59ed6d3 --- /dev/null +++ b/test/transform/resource/after-delombok/LoggerSlf4jOnRecord.java @@ -0,0 +1,3 @@ +record LoggerSlf4jOnRecord(String a, String b) { + private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LoggerSlf4jOnRecord.class); +} diff --git a/test/transform/resource/after-delombok/NonNullExistingConstructorOnRecord.java b/test/transform/resource/after-delombok/NonNullExistingConstructorOnRecord.java new file mode 100644 index 00000000..de2757ee --- /dev/null +++ b/test/transform/resource/after-delombok/NonNullExistingConstructorOnRecord.java @@ -0,0 +1,22 @@ +import lombok.NonNull; + +record NonNullOnRecord(@NonNull String a, @NonNull String b) { + public NonNullOnRecord(@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(@NonNull final String a, @NonNull final String b) { + if (a == null) { + throw new java.lang.NullPointerException("a is marked non-null but is null"); + } + if (b == null) { + throw new java.lang.NullPointerException("b is marked non-null but is null"); + } + this.a = a; + this.b = b; + } +} diff --git a/test/transform/resource/after-delombok/NonNullOnRecord.java b/test/transform/resource/after-delombok/NonNullOnRecord.java new file mode 100644 index 00000000..7147f49c --- /dev/null +++ b/test/transform/resource/after-delombok/NonNullOnRecord.java @@ -0,0 +1,22 @@ +import lombok.NonNull; + +record NonNullOnRecord(@NonNull String a, @NonNull String 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"; + } + + @java.lang.SuppressWarnings("all") + public NonNullOnRecord(@NonNull final String a, @NonNull final String b) { + if (a == null) { + throw new java.lang.NullPointerException("a is marked non-null but is null"); + } + if (b == null) { + throw new java.lang.NullPointerException("b is marked non-null but is null"); + } + this.a = a; + this.b = b; + } +} diff --git a/test/transform/resource/after-delombok/SetterOnRecord.java b/test/transform/resource/after-delombok/SetterOnRecord.java new file mode 100644 index 00000000..39a911ca --- /dev/null +++ b/test/transform/resource/after-delombok/SetterOnRecord.java @@ -0,0 +1,2 @@ +record SetterOnRecord(String a, String b) { +} diff --git a/test/transform/resource/after-delombok/SynchronizedInRecord.java b/test/transform/resource/after-delombok/SynchronizedInRecord.java new file mode 100644 index 00000000..67ca868a --- /dev/null +++ b/test/transform/resource/after-delombok/SynchronizedInRecord.java @@ -0,0 +1,6 @@ +// version 14: +record SynchronizedInRecord(String a, String b) { + public void foo() { + String foo = "bar"; + } +} diff --git a/test/transform/resource/after-delombok/ToStringOnRecord.java b/test/transform/resource/after-delombok/ToStringOnRecord.java new file mode 100644 index 00000000..84db33be --- /dev/null +++ b/test/transform/resource/after-delombok/ToStringOnRecord.java @@ -0,0 +1,2 @@ +record ToStringOnRecord(String a, String b) { +} diff --git a/test/transform/resource/after-delombok/UtilityClassOnRecord.java b/test/transform/resource/after-delombok/UtilityClassOnRecord.java new file mode 100644 index 00000000..fbe27370 --- /dev/null +++ b/test/transform/resource/after-delombok/UtilityClassOnRecord.java @@ -0,0 +1,2 @@ +record UtilityClassOnRecord(String a, String b) { +} diff --git a/test/transform/resource/after-delombok/ValueOnRecord.java b/test/transform/resource/after-delombok/ValueOnRecord.java new file mode 100644 index 00000000..d3d0e6db --- /dev/null +++ b/test/transform/resource/after-delombok/ValueOnRecord.java @@ -0,0 +1,2 @@ +record ValueOnRecord(String a, String b) { +} diff --git a/test/transform/resource/after-delombok/WithByOnRecord.java b/test/transform/resource/after-delombok/WithByOnRecord.java new file mode 100644 index 00000000..43a4c8c3 --- /dev/null +++ b/test/transform/resource/after-delombok/WithByOnRecord.java @@ -0,0 +1,6 @@ +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); + } +} diff --git a/test/transform/resource/after-delombok/WithOnRecord.java b/test/transform/resource/after-delombok/WithOnRecord.java new file mode 100644 index 00000000..bfb123bc --- /dev/null +++ b/test/transform/resource/after-delombok/WithOnRecord.java @@ -0,0 +1,11 @@ +record WithOnRecord(String a, String b) { + @java.lang.SuppressWarnings("all") + public WithOnRecord withA(final String a) { + return this.a == a ? this : new WithOnRecord(a, this.b); + } + + @java.lang.SuppressWarnings("all") + public WithOnRecord withB(final String b) { + return this.b == b ? this : new WithOnRecord(this.a, b); + } +} diff --git a/test/transform/resource/after-ecj/BuilderSimpleOnRecord.java b/test/transform/resource/after-ecj/BuilderSimpleOnRecord.java new file mode 100644 index 00000000..e73ed92e --- /dev/null +++ b/test/transform/resource/after-ecj/BuilderSimpleOnRecord.java @@ -0,0 +1,34 @@ +import java.util.List; +@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(); + } + public @java.lang.SuppressWarnings("all") BuilderSimpleOnRecord.BuilderSimpleOnRecordBuilder<T> l(final List<T> l) { + this.l = l; + return this; + } + public @java.lang.SuppressWarnings("all") BuilderSimpleOnRecord.BuilderSimpleOnRecordBuilder<T> a(final String a) { + this.a = a; + return this; + } + public @java.lang.SuppressWarnings("all") BuilderSimpleOnRecord<T> build() { + return new BuilderSimpleOnRecord<T>(this.l, this.a); + } + public @java.lang.Override @java.lang.SuppressWarnings("all") java.lang.String toString() { + return (((("BuilderSimpleOnRecord.BuilderSimpleOnRecordBuilder(l=" + this.l) + ", a=") + this.a) + ")"); + } + } +/* Implicit */ private final List<T> l; +/* Implicit */ private final String a; + public BuilderSimpleOnRecord(List<T> l, String a) { + super(); + .l = l; + .a = a; + } + protected static @java.lang.SuppressWarnings("all") <T>BuilderSimpleOnRecord.BuilderSimpleOnRecordBuilder<T> builder() { + return new BuilderSimpleOnRecord.BuilderSimpleOnRecordBuilder<T>(); + } +} diff --git a/test/transform/resource/after-ecj/BuilderSingularOnRecord.java b/test/transform/resource/after-ecj/BuilderSingularOnRecord.java new file mode 100644 index 00000000..b1d9cf39 --- /dev/null +++ b/test/transform/resource/after-ecj/BuilderSingularOnRecord.java @@ -0,0 +1,128 @@ +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 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; + private @java.lang.SuppressWarnings("all") java.util.ArrayList<java.lang.Object> rawList; + @java.lang.SuppressWarnings("all") BuilderSingularOnRecordBuilder() { + super(); + } + public @java.lang.SuppressWarnings("all") BuilderSingularOnRecord.BuilderSingularOnRecordBuilder<T> child(final T child) { + if ((this.children == null)) + this.children = new java.util.ArrayList<T>(); + this.children.add(child); + return this; + } + public @java.lang.SuppressWarnings("all") BuilderSingularOnRecord.BuilderSingularOnRecordBuilder<T> children(final java.util.Collection<? extends T> children) { + if ((children == null)) + { + throw new java.lang.NullPointerException("children cannot be null"); + } + if ((this.children == null)) + this.children = new java.util.ArrayList<T>(); + this.children.addAll(children); + return this; + } + public @java.lang.SuppressWarnings("all") BuilderSingularOnRecord.BuilderSingularOnRecordBuilder<T> clearChildren() { + if ((this.children != null)) + this.children.clear(); + return this; + } + public @java.lang.SuppressWarnings("all") BuilderSingularOnRecord.BuilderSingularOnRecordBuilder<T> scarf(final Number scarf) { + if ((this.scarves == null)) + this.scarves = new java.util.ArrayList<Number>(); + this.scarves.add(scarf); + return this; + } + public @java.lang.SuppressWarnings("all") BuilderSingularOnRecord.BuilderSingularOnRecordBuilder<T> scarves(final java.util.Collection<? extends Number> scarves) { + if ((scarves == null)) + { + throw new java.lang.NullPointerException("scarves cannot be null"); + } + if ((this.scarves == null)) + this.scarves = new java.util.ArrayList<Number>(); + this.scarves.addAll(scarves); + return this; + } + public @java.lang.SuppressWarnings("all") BuilderSingularOnRecord.BuilderSingularOnRecordBuilder<T> clearScarves() { + if ((this.scarves != null)) + this.scarves.clear(); + return this; + } + public @java.lang.SuppressWarnings("all") BuilderSingularOnRecord.BuilderSingularOnRecordBuilder<T> rawList(final java.lang.Object rawList) { + if ((this.rawList == null)) + this.rawList = new java.util.ArrayList<java.lang.Object>(); + this.rawList.add(rawList); + return this; + } + public @java.lang.SuppressWarnings("all") BuilderSingularOnRecord.BuilderSingularOnRecordBuilder<T> rawList(final java.util.Collection<?> rawList) { + if ((rawList == null)) + { + throw new java.lang.NullPointerException("rawList cannot be null"); + } + if ((this.rawList == null)) + this.rawList = new java.util.ArrayList<java.lang.Object>(); + this.rawList.addAll(rawList); + return this; + } + public @java.lang.SuppressWarnings("all") BuilderSingularOnRecord.BuilderSingularOnRecordBuilder<T> clearRawList() { + if ((this.rawList != null)) + this.rawList.clear(); + return this; + } + public @java.lang.SuppressWarnings("all") BuilderSingularOnRecord<T> build() { + java.util.List<T> children; + switch (((this.children == null) ? 0 : this.children.size())) { + case 0 : + children = java.util.Collections.emptyList(); + break; + case 1 : + children = java.util.Collections.singletonList(this.children.get(0)); + break; + default : + children = java.util.Collections.unmodifiableList(new java.util.ArrayList<T>(this.children)); + } + java.util.Collection<Number> scarves; + switch (((this.scarves == null) ? 0 : this.scarves.size())) { + case 0 : + scarves = java.util.Collections.emptyList(); + break; + case 1 : + scarves = java.util.Collections.singletonList(this.scarves.get(0)); + break; + default : + scarves = java.util.Collections.unmodifiableList(new java.util.ArrayList<Number>(this.scarves)); + } + java.util.List<java.lang.Object> rawList; + switch (((this.rawList == null) ? 0 : this.rawList.size())) { + case 0 : + rawList = java.util.Collections.emptyList(); + break; + case 1 : + rawList = java.util.Collections.singletonList(this.rawList.get(0)); + break; + default : + rawList = java.util.Collections.unmodifiableList(new java.util.ArrayList<java.lang.Object>(this.rawList)); + } + return new BuilderSingularOnRecord<T>(children, scarves, rawList); + } + public @java.lang.Override @java.lang.SuppressWarnings("all") java.lang.String toString() { + return (((((("BuilderSingularOnRecord.BuilderSingularOnRecordBuilder(children=" + this.children) + ", scarves=") + this.scarves) + ", rawList=") + this.rawList) + ")"); + } + } +/* Implicit */ private final List<T> children; +/* Implicit */ private final Collection<? extends Number> scarves; +/* Implicit */ private final List rawList; + public BuilderSingularOnRecord(@Singular List<T> children, @Singular Collection<? extends Number> scarves, @SuppressWarnings("all") @Singular("rawList") List rawList) { + super(); + .children = children; + .scarves = scarves; + .rawList = rawList; + } + public static @java.lang.SuppressWarnings("all") <T>BuilderSingularOnRecord.BuilderSingularOnRecordBuilder<T> builder() { + return new BuilderSingularOnRecord.BuilderSingularOnRecordBuilder<T>(); + } +} diff --git a/test/transform/resource/after-ecj/ConstructorsOnRecord.java b/test/transform/resource/after-ecj/ConstructorsOnRecord.java new file mode 100644 index 00000000..bfd9618f --- /dev/null +++ b/test/transform/resource/after-ecj/ConstructorsOnRecord.java @@ -0,0 +1,12 @@ +import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; +import lombok.RequiredArgsConstructor; +@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) { + super(); + .a = a; + .b = b; + } +} diff --git a/test/transform/resource/after-ecj/DataOnRecord.java b/test/transform/resource/after-ecj/DataOnRecord.java new file mode 100644 index 00000000..48783330 --- /dev/null +++ b/test/transform/resource/after-ecj/DataOnRecord.java @@ -0,0 +1,10 @@ +import lombok.Data; +@Data record DataOnRecord(String a, String b) { +/* Implicit */ private final String a; +/* Implicit */ private final String b; + public DataOnRecord(String a, String b) { + super(); + .a = a; + .b = b; + } +} diff --git a/test/transform/resource/after-ecj/EqualsAndHashCodeOnRecord.java b/test/transform/resource/after-ecj/EqualsAndHashCodeOnRecord.java new file mode 100644 index 00000000..60285186 --- /dev/null +++ b/test/transform/resource/after-ecj/EqualsAndHashCodeOnRecord.java @@ -0,0 +1,10 @@ +import lombok.EqualsAndHashCode; +@EqualsAndHashCode record EqualsAndHashCodeOnRecord(String a, String b) { +/* Implicit */ private final String a; +/* Implicit */ private final String b; + public EqualsAndHashCodeOnRecord(String a, String b) { + super(); + .a = a; + .b = b; + } +} diff --git a/test/transform/resource/after-ecj/FieldDefaultsOnRecord.java b/test/transform/resource/after-ecj/FieldDefaultsOnRecord.java new file mode 100644 index 00000000..95c49a42 --- /dev/null +++ b/test/transform/resource/after-ecj/FieldDefaultsOnRecord.java @@ -0,0 +1,9 @@ +@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) { + super(); + .a = a; + .b = b; + } +} diff --git a/test/transform/resource/after-ecj/FieldNameConstantsOnRecord.java b/test/transform/resource/after-ecj/FieldNameConstantsOnRecord.java new file mode 100644 index 00000000..b25fd6b3 --- /dev/null +++ b/test/transform/resource/after-ecj/FieldNameConstantsOnRecord.java @@ -0,0 +1,27 @@ +import lombok.experimental.FieldNameConstants; +import lombok.AccessLevel; +@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"; + <clinit>() { + } + private @java.lang.SuppressWarnings("all") Fields() { + super(); + } + } +/* Implicit */ private final String iAmADvdPlayer; +/* Implicit */ private final int $skipMe; +/* Implicit */ private final int andMe; +/* Implicit */ private final String butPrintMePlease; + static double skipMeToo; + <clinit>() { + } + public FieldNameConstantsOnRecord(String iAmADvdPlayer, int $skipMe, int andMe, String butPrintMePlease) { + super(); + .iAmADvdPlayer = iAmADvdPlayer; + .$skipMe = $skipMe; + .andMe = andMe; + .butPrintMePlease = butPrintMePlease; + } +} diff --git a/test/transform/resource/after-ecj/GetterOnRecord.java b/test/transform/resource/after-ecj/GetterOnRecord.java new file mode 100644 index 00000000..2cb61dba --- /dev/null +++ b/test/transform/resource/after-ecj/GetterOnRecord.java @@ -0,0 +1,10 @@ +import lombok.Getter; +@Getter record GetterOnRecord(String a, String b) { +/* Implicit */ private final String a; +/* Implicit */ private final String b; + public GetterOnRecord(String a, String b) { + super(); + .a = a; + .b = b; + } +} diff --git a/test/transform/resource/after-ecj/LoggerConfigOnRecord.java b/test/transform/resource/after-ecj/LoggerConfigOnRecord.java new file mode 100644 index 00000000..ca572860 --- /dev/null +++ b/test/transform/resource/after-ecj/LoggerConfigOnRecord.java @@ -0,0 +1,10 @@ +import lombok.extern.slf4j.Slf4j; +@Slf4j record LoggerConfigOnRecord(String a, String b) { +/* Implicit */ private final String a; +/* Implicit */ private final String b; + public LoggerConfigOnRecord(String a, String b) { + super(); + .a = a; + .b = b; + } +} diff --git a/test/transform/resource/after-ecj/LoggerSlf4jOnRecord.java b/test/transform/resource/after-ecj/LoggerSlf4jOnRecord.java new file mode 100644 index 00000000..804c8582 --- /dev/null +++ b/test/transform/resource/after-ecj/LoggerSlf4jOnRecord.java @@ -0,0 +1,13 @@ +import lombok.extern.slf4j.Slf4j; +@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; + <clinit>() { + } + public LoggerSlf4jOnRecord(String a, String b) { + super(); + .a = a; + .b = b; + } +} diff --git a/test/transform/resource/after-ecj/NonNullExistingConstructorOnRecord.java b/test/transform/resource/after-ecj/NonNullExistingConstructorOnRecord.java new file mode 100644 index 00000000..82bc6ffd --- /dev/null +++ b/test/transform/resource/after-ecj/NonNullExistingConstructorOnRecord.java @@ -0,0 +1,30 @@ +import lombok.NonNull; +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 NonNullOnRecord(@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) { + super(); + if ((a == null)) + { + throw new java.lang.NullPointerException("a is marked non-null but is null"); + } + if ((b == null)) + { + throw new java.lang.NullPointerException("b is marked non-null but is null"); + } + this.a = a; + this.b = b; + } +} diff --git a/test/transform/resource/after-ecj/NonNullOnRecord.java b/test/transform/resource/after-ecj/NonNullOnRecord.java new file mode 100644 index 00000000..7d71d9cc --- /dev/null +++ b/test/transform/resource/after-ecj/NonNullOnRecord.java @@ -0,0 +1,30 @@ +import lombok.NonNull; +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) { + super(); + if ((a == null)) + { + throw new java.lang.NullPointerException("a is marked non-null but is null"); + } + if ((b == null)) + { + throw new java.lang.NullPointerException("b is marked non-null but is null"); + } + this.a = a; + this.b = b; + } +} diff --git a/test/transform/resource/after-ecj/SetterOnRecord.java b/test/transform/resource/after-ecj/SetterOnRecord.java new file mode 100644 index 00000000..c9d3764f --- /dev/null +++ b/test/transform/resource/after-ecj/SetterOnRecord.java @@ -0,0 +1,10 @@ +import lombok.Setter; +@Setter record SetterOnRecord(String a, String b) { +/* Implicit */ private final String a; +/* Implicit */ private final String b; + public SetterOnRecord(String a, String b) { + super(); + .a = a; + .b = b; + } +} diff --git a/test/transform/resource/after-ecj/SynchronizedInRecord.java b/test/transform/resource/after-ecj/SynchronizedInRecord.java new file mode 100644 index 00000000..f90a85e2 --- /dev/null +++ b/test/transform/resource/after-ecj/SynchronizedInRecord.java @@ -0,0 +1,14 @@ +import lombok.Synchronized; +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; + public SynchronizedInRecord(String a, String b) { + super(); + .a = a; + .b = b; + } + public @Synchronized void foo() { + String foo = "bar"; + } +} diff --git a/test/transform/resource/after-ecj/ToStringOnRecord.java b/test/transform/resource/after-ecj/ToStringOnRecord.java new file mode 100644 index 00000000..8decb8d1 --- /dev/null +++ b/test/transform/resource/after-ecj/ToStringOnRecord.java @@ -0,0 +1,10 @@ +import lombok.ToString; +@ToString record ToStringOnRecord(String a, String b) { +/* Implicit */ private final String a; +/* Implicit */ private final String b; + public ToStringOnRecord(String a, String b) { + super(); + .a = a; + .b = b; + } +} diff --git a/test/transform/resource/after-ecj/UtilityClassOnRecord.java b/test/transform/resource/after-ecj/UtilityClassOnRecord.java new file mode 100644 index 00000000..036c0f86 --- /dev/null +++ b/test/transform/resource/after-ecj/UtilityClassOnRecord.java @@ -0,0 +1,10 @@ +import lombok.experimental.UtilityClass; +@UtilityClass record UtilityClassOnRecord(String a, String b) { +/* Implicit */ private final String a; +/* Implicit */ private final String b; + public UtilityClassOnRecord(String a, String b) { + super(); + .a = a; + .b = b; + } +} diff --git a/test/transform/resource/after-ecj/ValueOnRecord.java b/test/transform/resource/after-ecj/ValueOnRecord.java new file mode 100644 index 00000000..5b505c76 --- /dev/null +++ b/test/transform/resource/after-ecj/ValueOnRecord.java @@ -0,0 +1,10 @@ +import lombok.Value; +@Value record ValueOnRecord(String a, String b) { +/* Implicit */ private final String a; +/* Implicit */ private final String b; + public ValueOnRecord(String a, String b) { + super(); + .a = a; + .b = b; + } +} diff --git a/test/transform/resource/after-ecj/WithByOnRecord.java b/test/transform/resource/after-ecj/WithByOnRecord.java new file mode 100644 index 00000000..9048c9f4 --- /dev/null +++ b/test/transform/resource/after-ecj/WithByOnRecord.java @@ -0,0 +1,13 @@ +import lombok.experimental.WithBy; +record WithByOnRecord(String a, String b) { +/* Implicit */ private final String a; +/* Implicit */ private final String b; + public WithByOnRecord( String a, String b) { + super(); + .a = a; + .b = b; + } + public @java.lang.SuppressWarnings("all") WithByOnRecord withABy(final java.util.function.Function<? super String, ? extends String> transformer) { + return new WithByOnRecord(transformer.apply(this.a), this.b); + } +} diff --git a/test/transform/resource/after-ecj/WithOnRecord.java b/test/transform/resource/after-ecj/WithOnRecord.java new file mode 100644 index 00000000..5ab8d6ac --- /dev/null +++ b/test/transform/resource/after-ecj/WithOnRecord.java @@ -0,0 +1,16 @@ +import lombok.With; +@With record WithOnRecord(String a, String b) { +/* Implicit */ private final String a; +/* Implicit */ private final String b; + public WithOnRecord(String a, String b) { + super(); + .a = a; + .b = b; + } + public @java.lang.SuppressWarnings("all") WithOnRecord withA(final String a) { + return ((this.a == a) ? this : new WithOnRecord(a, this.b)); + } + public @java.lang.SuppressWarnings("all") WithOnRecord withB(final String b) { + return ((this.b == b) ? this : new WithOnRecord(this.a, b)); + } +} diff --git a/test/transform/resource/before/BuilderSimpleOnRecord.java b/test/transform/resource/before/BuilderSimpleOnRecord.java new file mode 100644 index 00000000..7968db64 --- /dev/null +++ b/test/transform/resource/before/BuilderSimpleOnRecord.java @@ -0,0 +1,7 @@ +// version 14: + +import java.util.List; + +@lombok.Builder(access = lombok.AccessLevel.PROTECTED) +record BuilderSimpleOnRecord<T>(List<T> l, String a) { +} diff --git a/test/transform/resource/before/BuilderSingularOnRecord.java b/test/transform/resource/before/BuilderSingularOnRecord.java new file mode 100644 index 00000000..0ffd80be --- /dev/null +++ b/test/transform/resource/before/BuilderSingularOnRecord.java @@ -0,0 +1,11 @@ +// version 14: + +import java.util.Collection; +import java.util.List; + +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) { +}
\ No newline at end of file diff --git a/test/transform/resource/before/ConstructorsOnRecord.java b/test/transform/resource/before/ConstructorsOnRecord.java new file mode 100644 index 00000000..d45495c8 --- /dev/null +++ b/test/transform/resource/before/ConstructorsOnRecord.java @@ -0,0 +1,11 @@ +// version 14: + +import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; +import lombok.RequiredArgsConstructor; + +@AllArgsConstructor +@RequiredArgsConstructor +@NoArgsConstructor +record ConstructorsOnRecord(String a, String b) { +}
\ No newline at end of file diff --git a/test/transform/resource/before/DataOnRecord.java b/test/transform/resource/before/DataOnRecord.java new file mode 100644 index 00000000..ed32c337 --- /dev/null +++ b/test/transform/resource/before/DataOnRecord.java @@ -0,0 +1,7 @@ +// version 14: + +import lombok.Data; + +@Data +record DataOnRecord(String a, String b) { +}
\ No newline at end of file diff --git a/test/transform/resource/before/EqualsAndHashCodeOnRecord.java b/test/transform/resource/before/EqualsAndHashCodeOnRecord.java new file mode 100644 index 00000000..5c295b3d --- /dev/null +++ b/test/transform/resource/before/EqualsAndHashCodeOnRecord.java @@ -0,0 +1,7 @@ +// version 14: + +import lombok.EqualsAndHashCode; + +@EqualsAndHashCode +record EqualsAndHashCodeOnRecord(String a, String b) { +}
\ No newline at end of file diff --git a/test/transform/resource/before/FieldDefaultsOnRecord.java b/test/transform/resource/before/FieldDefaultsOnRecord.java new file mode 100644 index 00000000..cf74508d --- /dev/null +++ b/test/transform/resource/before/FieldDefaultsOnRecord.java @@ -0,0 +1,5 @@ +// version 14: + +@lombok.experimental.FieldDefaults(makeFinal = true) +record FieldDefaultsOnRecord(String a, String b) { +}
\ No newline at end of file diff --git a/test/transform/resource/before/FieldNameConstantsOnRecord.java b/test/transform/resource/before/FieldNameConstantsOnRecord.java new file mode 100644 index 00000000..0905e082 --- /dev/null +++ b/test/transform/resource/before/FieldNameConstantsOnRecord.java @@ -0,0 +1,9 @@ +// version 14: + +import lombok.experimental.FieldNameConstants; +import lombok.AccessLevel; + +@FieldNameConstants(level = AccessLevel.PACKAGE) +record FieldNameConstantsOnRecord(String iAmADvdPlayer, int $skipMe, @FieldNameConstants.Exclude int andMe, String butPrintMePlease) { + static double skipMeToo; +}
\ No newline at end of file diff --git a/test/transform/resource/before/GetterOnRecord.java b/test/transform/resource/before/GetterOnRecord.java new file mode 100644 index 00000000..5a56a6d4 --- /dev/null +++ b/test/transform/resource/before/GetterOnRecord.java @@ -0,0 +1,7 @@ +// version 14: + +import lombok.Getter; + +@Getter +record GetterOnRecord(String a, String b) { +}
\ No newline at end of file diff --git a/test/transform/resource/before/LoggerConfigOnRecord.java b/test/transform/resource/before/LoggerConfigOnRecord.java new file mode 100644 index 00000000..c5f5a05a --- /dev/null +++ b/test/transform/resource/before/LoggerConfigOnRecord.java @@ -0,0 +1,8 @@ +// CONF: lombok.log.fieldIsStatic = false +// version 14: + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +record LoggerConfigOnRecord(String a, String b) { +}
\ No newline at end of file diff --git a/test/transform/resource/before/LoggerSlf4jOnRecord.java b/test/transform/resource/before/LoggerSlf4jOnRecord.java new file mode 100644 index 00000000..f3402742 --- /dev/null +++ b/test/transform/resource/before/LoggerSlf4jOnRecord.java @@ -0,0 +1,7 @@ +// version 14: + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +record LoggerSlf4jOnRecord(String a, String b) { +}
\ No newline at end of file diff --git a/test/transform/resource/before/NonNullExistingConstructorOnRecord.java b/test/transform/resource/before/NonNullExistingConstructorOnRecord.java new file mode 100644 index 00000000..1faf7d69 --- /dev/null +++ b/test/transform/resource/before/NonNullExistingConstructorOnRecord.java @@ -0,0 +1,9 @@ +// version 14: + +import lombok.NonNull; + +record NonNullOnRecord(@NonNull String a, @NonNull String b) { + public NonNullOnRecord(@NonNull String b) { + this("default", b); + } +}
\ No newline at end of file diff --git a/test/transform/resource/before/NonNullOnRecord.java b/test/transform/resource/before/NonNullOnRecord.java new file mode 100644 index 00000000..223f8cbb --- /dev/null +++ b/test/transform/resource/before/NonNullOnRecord.java @@ -0,0 +1,9 @@ +// version 14: + +import lombok.NonNull; + +record NonNullOnRecord(@NonNull String a, @NonNull String b) { + public void method(@NonNull String param) { + String asd = "a"; + } +}
\ No newline at end of file diff --git a/test/transform/resource/before/SetterOnRecord.java b/test/transform/resource/before/SetterOnRecord.java new file mode 100644 index 00000000..c91e06cd --- /dev/null +++ b/test/transform/resource/before/SetterOnRecord.java @@ -0,0 +1,7 @@ +// version 14: + +import lombok.Setter; + +@Setter +record SetterOnRecord(String a, String b) { +}
\ No newline at end of file diff --git a/test/transform/resource/before/SuperBuilderOnRecord.java b/test/transform/resource/before/SuperBuilderOnRecord.java new file mode 100644 index 00000000..8925176e --- /dev/null +++ b/test/transform/resource/before/SuperBuilderOnRecord.java @@ -0,0 +1,8 @@ +// skip compare content +// version 14: + +import lombok.experimental.SuperBuilder; + +@SuperBuilder +record SupeBuilderOnRecord(String a, String b) { +}
\ No newline at end of file diff --git a/test/transform/resource/before/SynchronizedInRecord.java b/test/transform/resource/before/SynchronizedInRecord.java new file mode 100644 index 00000000..99f87543 --- /dev/null +++ b/test/transform/resource/before/SynchronizedInRecord.java @@ -0,0 +1,10 @@ +// version 14: + +import lombok.Synchronized; + +record SynchronizedInRecord(String a, String b) { + @Synchronized + public void foo() { + String foo = "bar"; + } +}
\ No newline at end of file diff --git a/test/transform/resource/before/ToStringOnRecord.java b/test/transform/resource/before/ToStringOnRecord.java new file mode 100644 index 00000000..279c6f6c --- /dev/null +++ b/test/transform/resource/before/ToStringOnRecord.java @@ -0,0 +1,7 @@ +// version 14: + +import lombok.ToString; + +@ToString +record ToStringOnRecord(String a, String b) { +}
\ No newline at end of file diff --git a/test/transform/resource/before/UtilityClassOnRecord.java b/test/transform/resource/before/UtilityClassOnRecord.java new file mode 100644 index 00000000..1e3ebb38 --- /dev/null +++ b/test/transform/resource/before/UtilityClassOnRecord.java @@ -0,0 +1,7 @@ +// version 14: + +import lombok.experimental.UtilityClass; + +@UtilityClass +record UtilityClassOnRecord(String a, String b) { +}
\ No newline at end of file diff --git a/test/transform/resource/before/ValueOnRecord.java b/test/transform/resource/before/ValueOnRecord.java new file mode 100644 index 00000000..e1e49595 --- /dev/null +++ b/test/transform/resource/before/ValueOnRecord.java @@ -0,0 +1,7 @@ +// version 14: + +import lombok.Value; + +@Value +record ValueOnRecord(String a, String b) { +}
\ No newline at end of file diff --git a/test/transform/resource/before/WithByOnRecord.java b/test/transform/resource/before/WithByOnRecord.java new file mode 100644 index 00000000..98cbff9b --- /dev/null +++ b/test/transform/resource/before/WithByOnRecord.java @@ -0,0 +1,6 @@ +// version 14: + +import lombok.experimental.WithBy; + +record WithByOnRecord(@WithBy String a, String b) { +}
\ No newline at end of file diff --git a/test/transform/resource/before/WithOnRecord.java b/test/transform/resource/before/WithOnRecord.java new file mode 100644 index 00000000..211da3c8 --- /dev/null +++ b/test/transform/resource/before/WithOnRecord.java @@ -0,0 +1,7 @@ +// version 14: + +import lombok.With; + +@With +record WithOnRecord(String a, String b) { +}
\ No newline at end of file diff --git a/test/transform/resource/messages-delombok/ConstructorsOnRecord.java.messages b/test/transform/resource/messages-delombok/ConstructorsOnRecord.java.messages new file mode 100644 index 00000000..d1732a8c --- /dev/null +++ b/test/transform/resource/messages-delombok/ConstructorsOnRecord.java.messages @@ -0,0 +1,3 @@ +7 AllArgsConstructor is only supported on a class or an enum. +8 RequiredArgsConstructor is only supported on a class or an enum. +9 NoArgsConstructor is only supported on a class or an enum. diff --git a/test/transform/resource/messages-delombok/DataOnRecord.java.messages b/test/transform/resource/messages-delombok/DataOnRecord.java.messages new file mode 100644 index 00000000..42a9625b --- /dev/null +++ b/test/transform/resource/messages-delombok/DataOnRecord.java.messages @@ -0,0 +1 @@ +5 @Data is only supported on a class. diff --git a/test/transform/resource/messages-delombok/EqualsAndHashCodeOnRecord.java.messages b/test/transform/resource/messages-delombok/EqualsAndHashCodeOnRecord.java.messages new file mode 100644 index 00000000..daa53bcd --- /dev/null +++ b/test/transform/resource/messages-delombok/EqualsAndHashCodeOnRecord.java.messages @@ -0,0 +1 @@ +5 @EqualsAndHashCode is only supported on a class. diff --git a/test/transform/resource/messages-delombok/FieldDefaultsOnRecord.java.messages b/test/transform/resource/messages-delombok/FieldDefaultsOnRecord.java.messages new file mode 100644 index 00000000..1afb1bdf --- /dev/null +++ b/test/transform/resource/messages-delombok/FieldDefaultsOnRecord.java.messages @@ -0,0 +1 @@ +3 @FieldDefaults is only supported on a class or an enum. diff --git a/test/transform/resource/messages-delombok/GetterOnRecord.java.messages b/test/transform/resource/messages-delombok/GetterOnRecord.java.messages new file mode 100644 index 00000000..0830c585 --- /dev/null +++ b/test/transform/resource/messages-delombok/GetterOnRecord.java.messages @@ -0,0 +1 @@ +5 @Getter is only supported on a class, an enum, or a field. diff --git a/test/transform/resource/messages-delombok/LoggerConfigOnRecord.java.messages b/test/transform/resource/messages-delombok/LoggerConfigOnRecord.java.messages new file mode 100644 index 00000000..7dd3294e --- /dev/null +++ b/test/transform/resource/messages-delombok/LoggerConfigOnRecord.java.messages @@ -0,0 +1 @@ +6 Logger fields must be static in records. diff --git a/test/transform/resource/messages-delombok/SetterOnRecord.java.messages b/test/transform/resource/messages-delombok/SetterOnRecord.java.messages new file mode 100644 index 00000000..1913765c --- /dev/null +++ b/test/transform/resource/messages-delombok/SetterOnRecord.java.messages @@ -0,0 +1 @@ +5 @Setter is only supported on a class or a field. diff --git a/test/transform/resource/messages-delombok/SuperBuilderOnRecord.java.messages b/test/transform/resource/messages-delombok/SuperBuilderOnRecord.java.messages new file mode 100644 index 00000000..25b474ab --- /dev/null +++ b/test/transform/resource/messages-delombok/SuperBuilderOnRecord.java.messages @@ -0,0 +1 @@ +6 @SuperBuilder is only supported on types. diff --git a/test/transform/resource/messages-delombok/SynchronizedInRecord.java.messages b/test/transform/resource/messages-delombok/SynchronizedInRecord.java.messages new file mode 100644 index 00000000..d40e68b3 --- /dev/null +++ b/test/transform/resource/messages-delombok/SynchronizedInRecord.java.messages @@ -0,0 +1 @@ +5 @Synchronized is legal only on methods in classes and enums. diff --git a/test/transform/resource/messages-delombok/ToStringOnRecord.java.messages b/test/transform/resource/messages-delombok/ToStringOnRecord.java.messages new file mode 100644 index 00000000..0299664b --- /dev/null +++ b/test/transform/resource/messages-delombok/ToStringOnRecord.java.messages @@ -0,0 +1 @@ +5 @ToString is only supported on a class or enum. diff --git a/test/transform/resource/messages-delombok/UtilityClassErrors.java.messages b/test/transform/resource/messages-delombok/UtilityClassErrors.java.messages index 4afa12ec..0ff5b231 100644 --- a/test/transform/resource/messages-delombok/UtilityClassErrors.java.messages +++ b/test/transform/resource/messages-delombok/UtilityClassErrors.java.messages @@ -1,4 +1,4 @@ 4 @UtilityClasses cannot have declared constructors. 7 @UtilityClass cannot be placed on a method local or anonymous inner class, or any class nested in such a class. -12 @UtilityClass is only supported on a class (can't be an interface, enum, or annotation). +12 @UtilityClass is only supported on a class (can't be an interface, enum, annotation, or record). 17 @UtilityClass automatically makes the class static, however, this class cannot be made static.
\ No newline at end of file diff --git a/test/transform/resource/messages-delombok/UtilityClassOnRecord.java.messages b/test/transform/resource/messages-delombok/UtilityClassOnRecord.java.messages new file mode 100644 index 00000000..9de73ebd --- /dev/null +++ b/test/transform/resource/messages-delombok/UtilityClassOnRecord.java.messages @@ -0,0 +1 @@ +5 @UtilityClass is only supported on a class (can't be an interface, enum, annotation, or record). diff --git a/test/transform/resource/messages-delombok/ValueOnRecord.java.messages b/test/transform/resource/messages-delombok/ValueOnRecord.java.messages new file mode 100644 index 00000000..ebb71090 --- /dev/null +++ b/test/transform/resource/messages-delombok/ValueOnRecord.java.messages @@ -0,0 +1 @@ +5 @Value is only supported on a class. diff --git a/test/transform/resource/messages-ecj/ConstructorsOnRecord.java.messages b/test/transform/resource/messages-ecj/ConstructorsOnRecord.java.messages new file mode 100644 index 00000000..d1732a8c --- /dev/null +++ b/test/transform/resource/messages-ecj/ConstructorsOnRecord.java.messages @@ -0,0 +1,3 @@ +7 AllArgsConstructor is only supported on a class or an enum. +8 RequiredArgsConstructor is only supported on a class or an enum. +9 NoArgsConstructor is only supported on a class or an enum. diff --git a/test/transform/resource/messages-ecj/DataOnRecord.java.messages b/test/transform/resource/messages-ecj/DataOnRecord.java.messages new file mode 100644 index 00000000..42a9625b --- /dev/null +++ b/test/transform/resource/messages-ecj/DataOnRecord.java.messages @@ -0,0 +1 @@ +5 @Data is only supported on a class. diff --git a/test/transform/resource/messages-ecj/EqualsAndHashCodeOnRecord.java.messages b/test/transform/resource/messages-ecj/EqualsAndHashCodeOnRecord.java.messages new file mode 100644 index 00000000..daa53bcd --- /dev/null +++ b/test/transform/resource/messages-ecj/EqualsAndHashCodeOnRecord.java.messages @@ -0,0 +1 @@ +5 @EqualsAndHashCode is only supported on a class. diff --git a/test/transform/resource/messages-ecj/FieldDefaultsOnRecord.java.messages b/test/transform/resource/messages-ecj/FieldDefaultsOnRecord.java.messages new file mode 100644 index 00000000..1afb1bdf --- /dev/null +++ b/test/transform/resource/messages-ecj/FieldDefaultsOnRecord.java.messages @@ -0,0 +1 @@ +3 @FieldDefaults is only supported on a class or an enum. diff --git a/test/transform/resource/messages-ecj/GetterOnRecord.java.messages b/test/transform/resource/messages-ecj/GetterOnRecord.java.messages new file mode 100644 index 00000000..0830c585 --- /dev/null +++ b/test/transform/resource/messages-ecj/GetterOnRecord.java.messages @@ -0,0 +1 @@ +5 @Getter is only supported on a class, an enum, or a field. diff --git a/test/transform/resource/messages-ecj/LoggerConfigOnRecord.java.messages b/test/transform/resource/messages-ecj/LoggerConfigOnRecord.java.messages new file mode 100644 index 00000000..7dd3294e --- /dev/null +++ b/test/transform/resource/messages-ecj/LoggerConfigOnRecord.java.messages @@ -0,0 +1 @@ +6 Logger fields must be static in records. diff --git a/test/transform/resource/messages-ecj/SetterOnRecord.java.messages b/test/transform/resource/messages-ecj/SetterOnRecord.java.messages new file mode 100644 index 00000000..1913765c --- /dev/null +++ b/test/transform/resource/messages-ecj/SetterOnRecord.java.messages @@ -0,0 +1 @@ +5 @Setter is only supported on a class or a field. diff --git a/test/transform/resource/messages-ecj/SuperBuilderOnRecord.java.messages b/test/transform/resource/messages-ecj/SuperBuilderOnRecord.java.messages new file mode 100644 index 00000000..25b474ab --- /dev/null +++ b/test/transform/resource/messages-ecj/SuperBuilderOnRecord.java.messages @@ -0,0 +1 @@ +6 @SuperBuilder is only supported on types. diff --git a/test/transform/resource/messages-ecj/SynchronizedInRecord.java.messages b/test/transform/resource/messages-ecj/SynchronizedInRecord.java.messages new file mode 100644 index 00000000..af4b11f8 --- /dev/null +++ b/test/transform/resource/messages-ecj/SynchronizedInRecord.java.messages @@ -0,0 +1 @@ +6 @Synchronized is legal only on methods in classes and enums. diff --git a/test/transform/resource/messages-ecj/ToStringOnRecord.java.messages b/test/transform/resource/messages-ecj/ToStringOnRecord.java.messages new file mode 100644 index 00000000..0299664b --- /dev/null +++ b/test/transform/resource/messages-ecj/ToStringOnRecord.java.messages @@ -0,0 +1 @@ +5 @ToString is only supported on a class or enum. diff --git a/test/transform/resource/messages-ecj/UtilityClassErrors.java.messages b/test/transform/resource/messages-ecj/UtilityClassErrors.java.messages index 15c9b10f..6995eb65 100644 --- a/test/transform/resource/messages-ecj/UtilityClassErrors.java.messages +++ b/test/transform/resource/messages-ecj/UtilityClassErrors.java.messages @@ -1,4 +1,4 @@ 4 @UtilityClasses cannot have declared constructors. 7 @UtilityClass cannot be placed on a method local or anonymous inner class, or any class nested in such a class. -12 @UtilityClass is only supported on a class (can't be an interface, enum, or annotation) +12 @UtilityClass is only supported on a class (can't be an interface, enum, annotation, or record) 17 @UtilityClass automatically makes the class static, however, this class cannot be made static.
\ No newline at end of file diff --git a/test/transform/resource/messages-ecj/UtilityClassOnRecord.java.messages b/test/transform/resource/messages-ecj/UtilityClassOnRecord.java.messages new file mode 100644 index 00000000..9de73ebd --- /dev/null +++ b/test/transform/resource/messages-ecj/UtilityClassOnRecord.java.messages @@ -0,0 +1 @@ +5 @UtilityClass is only supported on a class (can't be an interface, enum, annotation, or record). diff --git a/test/transform/resource/messages-ecj/ValueOnRecord.java.messages b/test/transform/resource/messages-ecj/ValueOnRecord.java.messages new file mode 100644 index 00000000..ebb71090 --- /dev/null +++ b/test/transform/resource/messages-ecj/ValueOnRecord.java.messages @@ -0,0 +1 @@ +5 @Value is only supported on a class. |