diff options
author | Rawi01 <Rawi01@users.noreply.github.com> | 2020-09-10 10:20:12 +0200 |
---|---|---|
committer | Rawi01 <Rawi01@users.noreply.github.com> | 2020-09-10 10:32:14 +0200 |
commit | 0064c534273d9fb877f7e570f7a430060c88a5fb (patch) | |
tree | ee7089c1fbe948127aaea4c3317dd7dc18b0ee39 /src/core/lombok/javac | |
parent | 9148294f78a8e646ee131ca182a9b692bc028fdb (diff) | |
download | lombok-0064c534273d9fb877f7e570f7a430060c88a5fb.tar.gz lombok-0064c534273d9fb877f7e570f7a430060c88a5fb.tar.bz2 lombok-0064c534273d9fb877f7e570f7a430060c88a5fb.zip |
Add record support
Diffstat (limited to 'src/core/lombok/javac')
13 files changed, 78 insertions, 55 deletions
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; + } } |