[ https://issues.apache.org/jira/browse/GROOVY-7524?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14641551#comment-14641551 ]
Paul King commented on GROOVY-7524: ----------------------------------- Yes, because TupleConstructor and InheritConstructors occur at the same compilation phase, we currently run them in the order they appear in the source code file. There are tricks we could employ to guarantee ordering but we typically don't do that at present. The error message isn't perfect but here InheritConstructors is trying to be smart and only inherit constructors which are "missing" but it isn't smart enough to know about the chain of constructors which TupleConstructor produces, resulting in two no-arg constructors. When reversed, TupleConstructor will see the added inherited constructors and then not add more (unless {{force}} is in play in which case the same error will occur). As a general principal, we try to make transforms as independent as possible. We don't want each transform knowing about and making checks against a whole bunch of other transforms. This potentially allows transforms to be combined in ways we haven't thought of (and besides we can't check against user written transforms). This does leave us open to adverse transform interactions but that is in some ways part of the nature of transforms. The best we can do is try to describe transform behavior as best we can, be as explicit as we can about our assumptions and occasionally do some smart logic in the transforms to cater for obvious adverse behavior. > Inconsistant behavior when mixing TupleConstructor and InheritConstructors > -------------------------------------------------------------------------- > > Key: GROOVY-7524 > URL: https://issues.apache.org/jira/browse/GROOVY-7524 > Project: Groovy > Issue Type: Bug > Reporter: Keegan Witt > > This compiles, but the constructors from the subclass are deleted because of > GROOVY-7522. > {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} -- This message was sent by Atlassian JIRA (v6.3.4#6332)