You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by su...@apache.org on 2016/12/21 12:00:44 UTC
[02/21] groovy git commit: GROOVY-8011: @ToString if used with
includes='prop1,
prop2' could allow the pseudo prop name 'super' as an alternative to using the
includeSuper flag (closes #467)
GROOVY-8011: @ToString if used with includes='prop1,prop2' could allow the pseudo prop name 'super' as an alternative to using the includeSuper flag (closes #467)
Project: http://git-wip-us.apache.org/repos/asf/groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/9d2b7fd2
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/9d2b7fd2
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/9d2b7fd2
Branch: refs/heads/parrot
Commit: 9d2b7fd219ff4ce11a6e75a2c530923f8293844b
Parents: e9e7724
Author: paulk <pa...@asert.com.au>
Authored: Thu Dec 1 14:55:20 2016 +1000
Committer: paulk <pa...@asert.com.au>
Committed: Fri Dec 2 04:34:09 2016 +1000
----------------------------------------------------------------------
src/main/groovy/transform/ToString.java | 15 +++----
.../transform/ToStringASTTransformation.java | 42 +++++++++++++++-----
.../transform/ToStringTransformTest.groovy | 21 ++++++++++
3 files changed, 61 insertions(+), 17 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/groovy/blob/9d2b7fd2/src/main/groovy/transform/ToString.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/transform/ToString.java b/src/main/groovy/transform/ToString.java
index c1e2145..9fc4627 100644
--- a/src/main/groovy/transform/ToString.java
+++ b/src/main/groovy/transform/ToString.java
@@ -273,6 +273,7 @@ public @interface ToString {
* can be used in addition to an array (using Groovy's literal list notation) of String values.
* The default value is a special marker value indicating that no includes are defined; all fields and/or properties
* are included if 'includes' remains undefined and 'excludes' is explicitly or implicitly an empty list.
+ * The special name 'super' can be used instead of using the 'includeSuper' flag.
*/
String[] includes() default {Undefined.STRING};
@@ -328,11 +329,11 @@ public @interface ToString {
*/
boolean cache() default false;
- /**
- * Whether to include all fields and/or properties in the generated toString, including those with names that
- * are considered internal.
- *
- * @since 2.5.0
- */
- boolean allNames() default false;
+ /**
+ * Whether to include all fields and/or properties in the generated toString, including those with names that
+ * are considered internal.
+ *
+ * @since 2.5.0
+ */
+ boolean allNames() default false;
}
http://git-wip-us.apache.org/repos/asf/groovy/blob/9d2b7fd2/src/main/org/codehaus/groovy/transform/ToStringASTTransformation.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/transform/ToStringASTTransformation.java b/src/main/org/codehaus/groovy/transform/ToStringASTTransformation.java
index 5040414..3cba4a5 100644
--- a/src/main/org/codehaus/groovy/transform/ToStringASTTransformation.java
+++ b/src/main/org/codehaus/groovy/transform/ToStringASTTransformation.java
@@ -37,6 +37,7 @@ import org.codehaus.groovy.ast.stmt.Statement;
import org.codehaus.groovy.ast.tools.BeanUtils;
import org.codehaus.groovy.control.CompilePhase;
import org.codehaus.groovy.control.SourceUnit;
+import org.codehaus.groovy.runtime.DefaultGroovyMethods;
import org.codehaus.groovy.runtime.InvokerHelper;
import org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport;
@@ -70,20 +71,23 @@ public class ToStringASTTransformation extends AbstractASTTransformation {
boolean includeSuper = memberHasValue(anno, "includeSuper", true);
boolean includeSuperProperties = memberHasValue(anno, "includeSuperProperties", true);
boolean cacheToString = memberHasValue(anno, "cache", true);
+ List<String> excludes = getMemberStringList(anno, "excludes");
+ List<String> includes = getMemberStringList(anno, "includes");
+ if (includes != null && includes.contains("super")) {
+ includeSuper = true;
+ }
if (includeSuper && cNode.getSuperClass().getName().equals("java.lang.Object")) {
addError("Error during " + MY_TYPE_NAME + " processing: includeSuper=true but '" + cNode.getName() + "' has no super class.", anno);
}
boolean includeNames = memberHasValue(anno, "includeNames", true);
boolean includeFields = memberHasValue(anno, "includeFields", true);
- List<String> excludes = getMemberStringList(anno, "excludes");
- List<String> includes = getMemberStringList(anno, "includes");
boolean ignoreNulls = memberHasValue(anno, "ignoreNulls", true);
boolean includePackage = !memberHasValue(anno, "includePackage", false);
boolean allProperties = !memberHasValue(anno, "allProperties", false);
boolean allNames = memberHasValue(anno, "allNames", true);
if (!checkIncludeExcludeUndefinedAware(anno, excludes, includes, MY_TYPE_NAME)) return;
- if (!checkPropertyList(cNode, includes, "includes", anno, MY_TYPE_NAME, includeFields)) return;
+ if (!checkPropertyList(cNode, includes != null ? DefaultGroovyMethods.minus(includes, "super") : null, "includes", anno, MY_TYPE_NAME, includeFields)) return;
if (!checkPropertyList(cNode, excludes, "excludes", anno, MY_TYPE_NAME, includeFields)) return;
createToString(cNode, includeSuper, includeFields, excludes, includes, includeNames, ignoreNulls, includePackage, cacheToString, includeSuperProperties, allProperties, allNames);
}
@@ -137,10 +141,23 @@ public class ToStringASTTransformation extends AbstractASTTransformation {
ClassHelper.STRING_TYPE, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, body));
}
+ private static class ToStringElement {
+ ToStringElement(Expression value, String name, boolean canBeSelf) {
+ this.value = value;
+ this.name = name;
+ this.canBeSelf = canBeSelf;
+ }
+
+ Expression value;
+ String name;
+ boolean canBeSelf;
+ }
+
private static Expression calculateToStringStatements(ClassNode cNode, boolean includeSuper, boolean includeFields, List<String> excludes, List<String> includes, boolean includeNames, boolean ignoreNulls, boolean includePackage, boolean includeSuperProperties, boolean allProperties, BlockStatement body, boolean allNames) {
// def _result = new StringBuilder()
final Expression result = varX("_result");
body.addStatement(declS(result, ctorX(STRINGBUILDER_TYPE)));
+ List<ToStringElement> elements = new ArrayList<ToStringElement>();
// def $toStringFirst = true
final VariableExpression first = varX("$toStringFirst");
@@ -155,7 +172,7 @@ public class ToStringASTTransformation extends AbstractASTTransformation {
for (PropertyNode pNode : pList) {
if (shouldSkip(pNode.getName(), excludes, includes, allNames)) continue;
Expression getter = getterThisX(cNode, pNode);
- appendValue(cNode, body, result, first, getter, pNode.getOriginType(), pNode.getName(), includeNames, ignoreNulls);
+ elements.add(new ToStringElement(getter, pNode.getName(), canBeSelf(cNode, pNode.getOriginType())));
}
// append fields if needed
@@ -164,16 +181,18 @@ public class ToStringASTTransformation extends AbstractASTTransformation {
fList.addAll(getInstanceNonPropertyFields(cNode));
for (FieldNode fNode : fList) {
if (shouldSkip(fNode.getName(), excludes, includes, allNames)) continue;
- appendValue(cNode, body, result, first, varX(fNode), fNode.getType(), fNode.getName(), includeNames, ignoreNulls);
+ elements.add(new ToStringElement(varX(fNode), fNode.getName(), canBeSelf(cNode, fNode.getType())));
}
}
// append super if needed
if (includeSuper) {
- appendCommaIfNotFirst(body, result, first);
- appendPrefix(body, result, "super", includeNames);
// not through MOP to avoid infinite recursion
- body.addStatement(appendS(result, callSuperX("toString")));
+ elements.add(new ToStringElement(callSuperX("toString"), "super", false));
+ }
+
+ for (ToStringElement el : elements) {
+ appendValue(body, result, first, el.value, el.name, includeNames, ignoreNulls, el.canBeSelf);
}
// wrap up
@@ -183,12 +202,11 @@ public class ToStringASTTransformation extends AbstractASTTransformation {
return toString;
}
- private static void appendValue(ClassNode cNode, BlockStatement body, Expression result, VariableExpression first, Expression value, ClassNode valueType, String name, boolean includeNames, boolean ignoreNulls) {
+ private static void appendValue(BlockStatement body, Expression result, VariableExpression first, Expression value, String name, boolean includeNames, boolean ignoreNulls, boolean canBeSelf) {
final BlockStatement thenBlock = new BlockStatement();
final Statement appendValue = ignoreNulls ? ifS(notNullX(value), thenBlock) : thenBlock;
appendCommaIfNotFirst(thenBlock, result, first);
appendPrefix(thenBlock, result, name, includeNames);
- boolean canBeSelf = StaticTypeCheckingSupport.implementsInterfaceOrIsSubclassOf(valueType, cNode);
if (canBeSelf) {
thenBlock.addStatement(ifElseS(
sameX(value, new VariableExpression("this")),
@@ -201,6 +219,10 @@ public class ToStringASTTransformation extends AbstractASTTransformation {
body.addStatement(appendValue);
}
+ private static boolean canBeSelf(ClassNode cNode, ClassNode valueType) {
+ return StaticTypeCheckingSupport.implementsInterfaceOrIsSubclassOf(valueType, cNode);
+ }
+
private static void appendCommaIfNotFirst(BlockStatement body, Expression result, VariableExpression first) {
// if ($toStringFirst) $toStringFirst = false else result.append(", ")
body.addStatement(ifElseS(
http://git-wip-us.apache.org/repos/asf/groovy/blob/9d2b7fd2/src/test/org/codehaus/groovy/transform/ToStringTransformTest.groovy
----------------------------------------------------------------------
diff --git a/src/test/org/codehaus/groovy/transform/ToStringTransformTest.groovy b/src/test/org/codehaus/groovy/transform/ToStringTransformTest.groovy
index 7f28237..18f5d10 100644
--- a/src/test/org/codehaus/groovy/transform/ToStringTransformTest.groovy
+++ b/src/test/org/codehaus/groovy/transform/ToStringTransformTest.groovy
@@ -448,4 +448,25 @@ class ToStringTransformTest extends GroovyShellTestCase {
'''
}
+ void testIncludesWithSuper_Groovy8011() {
+ def toString = evaluate("""
+ import groovy.transform.*
+
+ @ToString
+ class Foo {
+ String baz = 'baz'
+ }
+
+ @ToString(includes='super,num,blah', includeNames=true)
+ class Bar extends Foo {
+ String blah = 'blah'
+ int num = 42
+ }
+
+ new Bar().toString()
+ """)
+
+ assert toString.contains('super:Foo(baz)')
+ }
+
}