[ https://issues.apache.org/jira/browse/GROOVY-7524?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14995576#comment-14995576 ]
Paul King edited comment on GROOVY-7524 at 11/8/15 10:29 PM: ------------------------------------------------------------- I actually might tweak the wording on the added comment. It should read more along the lines of use together with extreme care. They can be used together as the following example shows: {code} import groovy.transform.* @TupleConstructor class NameId { String name Integer id } @ToString(includeSuperProperties=true, ignoreNulls=true, includeNames=true) @InheritConstructors @TupleConstructor(force=true, defaults=false) class Cat extends NameId { Double age } assert new Cat("Mr. Bigglesworth").toString() == 'Cat(name:Mr. Bigglesworth)' assert new Cat("Mr. Bigglesworth", 42).toString() == 'Cat(name:Mr. Bigglesworth, id:42)' assert new Cat(3.5).toString() == 'Cat(age:3.5)' assert new Cat().toString() == 'Cat()' {code} But while the above example works fine, without the "force=true" and "defaults=false" attributes for TupleConstructor, the example would break horribly or totally ignore one of the annotations depending on what was left out. was (Author: paulk): I actually might tweak the wording on the added comment. It should read more along the lines of use together with extreme care as the following example shows: {code} import groovy.transform.* @TupleConstructor class NameId { String name Integer id } @ToString(includeSuperProperties=true, ignoreNulls=true, includeNames=true) @InheritConstructors @TupleConstructor(force=true, defaults=false) class Cat extends NameId { Double age } assert new Cat("Mr. Bigglesworth").toString() == 'Cat(name:Mr. Bigglesworth)' assert new Cat("Mr. Bigglesworth", 42).toString() == 'Cat(name:Mr. Bigglesworth, id:42)' assert new Cat(3.5).toString() == 'Cat(age:3.5)' assert new Cat().toString() == 'Cat()' {code} As an example, while the above works fine, without the "force=true" and "defaults=false" attributes for TupleConstructor, the example would break horribly. > Document that TupleConstructor and InheritConstructors shouldn't be mixed > ------------------------------------------------------------------------- > > Key: GROOVY-7524 > URL: https://issues.apache.org/jira/browse/GROOVY-7524 > Project: Groovy > Issue Type: Documentation > Reporter: Keegan Witt > Assignee: Keegan Witt > Fix For: 2.4.6 > > > This compiles > {code:java} > @groovy.transform.TupleConstructor > class Animal { > int age > } > @groovy.transform.InheritConstructors > @groovy.transform.TupleConstructor > class Cat extends Animal { > String name > } > {code} > But simply changing the order of the annotations, like this > {code:java} > @groovy.transform.TupleConstructor > class Animal { > int age > } > @groovy.transform.TupleConstructor > @groovy.transform.InheritConstructors > class Cat extends Animal { > String name > } > {code} > causes > {noformat}java.util.NoSuchElementException > at java.util.TreeMap$PrivateEntryIterator.nextEntry(TreeMap.java:1205) > at java.util.TreeMap$KeyIterator.next(TreeMap.java:1261) > at > org.codehaus.groovy.classgen.asm.InvocationWriter.makeMOPBasedConstructorCall(InvocationWriter.java:723) > at > org.codehaus.groovy.classgen.asm.InvocationWriter.visitSpecialConstructorCall(InvocationWriter.java:629) > at > org.codehaus.groovy.classgen.asm.InvocationWriter.writeSpecialConstructorCall(InvocationWriter.java:619) > at > org.codehaus.groovy.classgen.AsmClassGenerator.visitConstructorCallExpression(AsmClassGenerator.java:813) > at > org.codehaus.groovy.ast.expr.ConstructorCallExpression.visit(ConstructorCallExpression.java:44) > at > org.codehaus.groovy.classgen.asm.StatementWriter.writeExpressionStatement(StatementWriter.java:604) > at > org.codehaus.groovy.classgen.asm.OptimizingStatementWriter.writeExpressionStatement(OptimizingStatementWriter.java:354) > at > org.codehaus.groovy.classgen.AsmClassGenerator.visitExpressionStatement(AsmClassGenerator.java:619) > at > org.codehaus.groovy.ast.stmt.ExpressionStatement.visit(ExpressionStatement.java:40) > at > org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitClassCodeContainer(ClassCodeVisitorSupport.java:101) > at > org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitConstructorOrMethod(ClassCodeVisitorSupport.java:112) > at > org.codehaus.groovy.classgen.AsmClassGenerator.visitStdMethod(AsmClassGenerator.java:429) > at > org.codehaus.groovy.classgen.AsmClassGenerator.visitConstructorOrMethod(AsmClassGenerator.java:386) > at > org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitConstructor(ClassCodeVisitorSupport.java:119) > at > org.codehaus.groovy.classgen.AsmClassGenerator.visitConstructor(AsmClassGenerator.java:501) > at org.codehaus.groovy.ast.ClassNode.visitContents(ClassNode.java:1079) > at > org.codehaus.groovy.ast.ClassCodeVisitorSupport.visitClass(ClassCodeVisitorSupport.java:50) > at > org.codehaus.groovy.classgen.AsmClassGenerator.visitClass(AsmClassGenerator.java:232) > at > org.codehaus.groovy.control.CompilationUnit$16.call(CompilationUnit.java:810) > at > org.codehaus.groovy.control.CompilationUnit.applyToPrimaryClassNodes(CompilationUnit.java:1052) > at > org.codehaus.groovy.control.CompilationUnit.doPhaseOperation(CompilationUnit.java:588) > at > org.codehaus.groovy.control.CompilationUnit.processPhaseOperations(CompilationUnit.java:566) > at > org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:543) > at > groovy.lang.GroovyClassLoader.doParseClass(GroovyClassLoader.java:297) > at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:267) > ...{noformat} > We should document that these transformations can interfere with each other, > and generally shouldn't be used concurrently. -- This message was sent by Atlassian JIRA (v6.3.4#6332)