From 7e79316a1f28d1eb1ef8569119b97a70387fd6c6 Mon Sep 17 00:00:00 2001 From: Roel Spilker Date: Tue, 6 Nov 2018 00:27:02 +0100 Subject: Improve toString generation for enums. Fixes #1916 --- doc/changelog.markdown | 1 + src/core/lombok/core/LombokNode.java | 3 +- src/core/lombok/eclipse/EclipseNode.java | 7 ++- .../lombok/eclipse/handlers/HandleToString.java | 69 +++++++++++++++------- src/core/lombok/javac/JavacNode.java | 8 ++- src/core/lombok/javac/handlers/HandleToString.java | 21 +++++-- .../resource/after-delombok/DataOnEnum.java | 2 +- .../resource/after-delombok/ToStringEnum.java | 28 +++++++++ test/transform/resource/after-ecj/DataOnEnum.java | 2 +- .../transform/resource/after-ecj/ToStringEnum.java | 41 +++++++++++++ test/transform/resource/before/ToStringEnum.java | 17 ++++++ 11 files changed, 168 insertions(+), 31 deletions(-) create mode 100644 test/transform/resource/after-delombok/ToStringEnum.java create mode 100644 test/transform/resource/after-ecj/ToStringEnum.java create mode 100644 test/transform/resource/before/ToStringEnum.java diff --git a/doc/changelog.markdown b/doc/changelog.markdown index 78588c36..4a19ed73 100644 --- a/doc/changelog.markdown +++ b/doc/changelog.markdown @@ -5,6 +5,7 @@ Lombok Changelog * BUGFIX: Since version 1.18.4, the delombok ant task didn't work and errored with a `NoClassDefFoundError`. [Issue #1932](https://github.com/rzwitserloot/lombok/issues/1932) * FEATURE: The `@FieldNameConstants` feature now allows you to write the inner type by hand and add whatever you like to it; lombok will add the constants to this class. See the updated [FieldNameConstants feature](https://projectlombok.org/features/experimental/FieldNameConstants) page. * FEATURE: There is now a `lombok.config` key to configure `@ToString`'s call super behavior; it's just like `@EqualsAndHashCode` which has had it for a while now. [Issue #1918](https://github.com/rzwitserloot/lombok/issues/1918) +* ENHANCEMENT: The toString generation of enums now contains the name of the enum constant. [Issue #1916](https://github.com/rzwitserloot/lombok/issues/1916) ### v1.18.4 (October 30th, 2018) * PLATFORM: Support for Eclipse Photon. [Issue #1831](https://github.com/rzwitserloot/lombok/issues/1831) diff --git a/src/core/lombok/core/LombokNode.java b/src/core/lombok/core/LombokNode.java index 5a0842bc..ae8fd325 100644 --- a/src/core/lombok/core/LombokNode.java +++ b/src/core/lombok/core/LombokNode.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009-2013 The Project Lombok Authors. + * Copyright (C) 2009-2018 The Project Lombok Authors. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -279,6 +279,7 @@ public abstract class LombokNode, L extends LombokNode { boolean includeNames, boolean callSuper, ASTNode source, FieldAccess fieldAccess) { String typeName = getTypeName(type); + boolean isEnum = type.isEnumType(); + char[] suffix = ")".toCharArray(); String infixS = ", "; char[] infix = infixS.toCharArray(); @@ -172,31 +176,54 @@ public class HandleToString extends EclipseAnnotationHandler { long p = (long)pS << 32 | pE; final int PLUS = OperatorIds.PLUS; - char[] prefix; + String prefix; if (callSuper) { - prefix = (typeName + "(super=").toCharArray(); + prefix = "(super="; } else if (members.isEmpty()) { - prefix = (typeName + "()").toCharArray(); + prefix = isEnum ? "" : "()"; } else if (includeNames) { Included firstMember = members.iterator().next(); String name = firstMember.getInc() == null ? "" : firstMember.getInc().name(); if (name.isEmpty()) name = firstMember.getNode().getName(); - prefix = (typeName + "(" + name + "=").toCharArray(); + prefix = "(" + name + "="; } else { - prefix = (typeName + "(").toCharArray(); + prefix = "("; } boolean first = true; - Expression current = new StringLiteral(prefix, pS, pE, 0); - setGeneratedBy(current, source); + Expression current; + if (!isEnum) { + current = new StringLiteral((typeName + prefix).toCharArray(), pS, pE, 0); + setGeneratedBy(current, source); + } else { + current = new StringLiteral((typeName + ".").toCharArray(), pS, pE, 0); + setGeneratedBy(current, source); + + MessageSend thisName = new MessageSend(); + thisName.sourceStart = pS; thisName.sourceEnd = pE; + setGeneratedBy(thisName, source); + thisName.receiver = new ThisReference(pS, pE); + setGeneratedBy(thisName.receiver, source); + thisName.selector = "name".toCharArray(); + current = new BinaryExpression(current, thisName, PLUS); + setGeneratedBy(current, source); + + if (!prefix.isEmpty()) { + StringLiteral px = new StringLiteral(prefix.toCharArray(), pS, pE, 0); + setGeneratedBy(px, source); + current = new BinaryExpression(current, px, PLUS); + current.sourceStart = pS; current.sourceEnd = pE; + setGeneratedBy(current, source); + } + } if (callSuper) { MessageSend callToSuper = new MessageSend(); callToSuper.sourceStart = pS; callToSuper.sourceEnd = pE; setGeneratedBy(callToSuper, source); callToSuper.receiver = new SuperReference(pS, pE); - setGeneratedBy(callToSuper, source); + setGeneratedBy(callToSuper.receiver, source); callToSuper.selector = "toString".toCharArray(); current = new BinaryExpression(current, callToSuper, PLUS); setGeneratedBy(current, source); diff --git a/src/core/lombok/javac/JavacNode.java b/src/core/lombok/javac/JavacNode.java index 3963c892..f119f1f9 100644 --- a/src/core/lombok/javac/JavacNode.java +++ b/src/core/lombok/javac/JavacNode.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009-2017 The Project Lombok Authors. + * Copyright (C) 2009-2018 The Project Lombok Authors. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -317,6 +317,12 @@ public class JavacNode extends lombok.core.LombokNode { boolean first = true; String typeName = getTypeName(typeNode); + boolean isEnum = typeNode.isEnumType(); + String infix = ", "; String suffix = ")"; String prefix; if (callSuper) { - prefix = typeName + "(super="; + prefix = "(super="; } else if (members.isEmpty()) { - prefix = typeName + "()"; + prefix = isEnum ? "" : "()"; } else if (includeNames) { Included firstMember = members.iterator().next(); String name = firstMember.getInc() == null ? "" : firstMember.getInc().name(); if (name.isEmpty()) name = firstMember.getNode().getName(); - prefix = typeName + "(" + name + "="; + prefix = "(" + name + "="; + } else { + prefix = "("; + } + + JCExpression current; + if (!isEnum) { + current = maker.Literal(typeName + prefix); } else { - prefix = typeName + "("; + current = maker.Binary(CTC_PLUS, maker.Literal(typeName + "."), maker.Apply(List.nil(), + maker.Select(maker.Ident(typeNode.toName("this")), typeNode.toName("name")), + List.nil())); + if (!prefix.isEmpty()) current = maker.Binary(CTC_PLUS, current, maker.Literal(prefix)); } - JCExpression current = maker.Literal(prefix); if (callSuper) { JCMethodInvocation callToSuper = maker.Apply(List.nil(), diff --git a/test/transform/resource/after-delombok/DataOnEnum.java b/test/transform/resource/after-delombok/DataOnEnum.java index 2486646b..6b5779e8 100644 --- a/test/transform/resource/after-delombok/DataOnEnum.java +++ b/test/transform/resource/after-delombok/DataOnEnum.java @@ -8,7 +8,7 @@ public enum DataOnEnum { @java.lang.Override @java.lang.SuppressWarnings("all") public java.lang.String toString() { - return "DataOnEnum(someField=" + this.getSomeField() + ")"; + return "DataOnEnum." + this.name() + "(someField=" + this.getSomeField() + ")"; } @java.lang.SuppressWarnings("all") private DataOnEnum(final String someField) { diff --git a/test/transform/resource/after-delombok/ToStringEnum.java b/test/transform/resource/after-delombok/ToStringEnum.java new file mode 100644 index 00000000..9d852e19 --- /dev/null +++ b/test/transform/resource/after-delombok/ToStringEnum.java @@ -0,0 +1,28 @@ +enum ToStringEnum1 { + CONSTANT; + @java.lang.Override + @java.lang.SuppressWarnings("all") + public java.lang.String toString() { + return "ToStringEnum1." + this.name(); + } +} +enum ToStringEnum2 { + CONSTANT; + int x; + String name; + @java.lang.Override + @java.lang.SuppressWarnings("all") + public java.lang.String toString() { + return "ToStringEnum2." + this.name() + "(x=" + this.x + ", name=" + this.name + ")"; + } +} +class ToStringEnum3 { + enum MemberEnum { + CONSTANT; + @java.lang.Override + @java.lang.SuppressWarnings("all") + public java.lang.String toString() { + return "ToStringEnum3.MemberEnum." + this.name(); + } + } +} \ No newline at end of file diff --git a/test/transform/resource/after-ecj/DataOnEnum.java b/test/transform/resource/after-ecj/DataOnEnum.java index 0f07088e..31eb12ec 100644 --- a/test/transform/resource/after-ecj/DataOnEnum.java +++ b/test/transform/resource/after-ecj/DataOnEnum.java @@ -7,7 +7,7 @@ public @lombok.Getter @lombok.ToString @lombok.RequiredArgsConstructor enum Data return this.someField; } public @java.lang.Override @java.lang.SuppressWarnings("all") java.lang.String toString() { - return (("DataOnEnum(someField=" + this.getSomeField()) + ")"); + return (((("DataOnEnum." + this.name()) + "(someField=") + this.getSomeField()) + ")"); } private @java.lang.SuppressWarnings("all") DataOnEnum(final String someField) { super(); diff --git a/test/transform/resource/after-ecj/ToStringEnum.java b/test/transform/resource/after-ecj/ToStringEnum.java new file mode 100644 index 00000000..d4ab5a93 --- /dev/null +++ b/test/transform/resource/after-ecj/ToStringEnum.java @@ -0,0 +1,41 @@ +import lombok.ToString; +@ToString enum ToStringEnum1 { + CONSTANT(), + () { + } + ToStringEnum1() { + super(); + } + public @java.lang.Override @java.lang.SuppressWarnings("all") java.lang.String toString() { + return ("ToStringEnum1." + this.name()); + } +} +@ToString enum ToStringEnum2 { + CONSTANT(), + int x; + String name; + () { + } + ToStringEnum2() { + super(); + } + public @java.lang.Override @java.lang.SuppressWarnings("all") java.lang.String toString() { + return (((((("ToStringEnum2." + this.name()) + "(x=") + this.x) + ", name=") + this.name) + ")"); + } +} +class ToStringEnum3 { + @ToString enum MemberEnum { + CONSTANT(), + () { + } + MemberEnum() { + super(); + } + public @java.lang.Override @java.lang.SuppressWarnings("all") java.lang.String toString() { + return ("ToStringEnum3.MemberEnum." + this.name()); + } + } + ToStringEnum3() { + super(); + } +} \ No newline at end of file diff --git a/test/transform/resource/before/ToStringEnum.java b/test/transform/resource/before/ToStringEnum.java new file mode 100644 index 00000000..8b8ad576 --- /dev/null +++ b/test/transform/resource/before/ToStringEnum.java @@ -0,0 +1,17 @@ +import lombok.ToString; +@ToString +enum ToStringEnum1 { + CONSTANT; +} +@ToString +enum ToStringEnum2 { + CONSTANT(); + int x; + String name; +} +class ToStringEnum3 { + @ToString + enum MemberEnum { + CONSTANT; + } +} \ No newline at end of file -- cgit