GROOVY-7966: Change in source order changes output in Java+Groovy joint compilation (closes #471)
Project: http://git-wip-us.apache.org/repos/asf/groovy/repo Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/6c410852 Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/6c410852 Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/6c410852 Branch: refs/heads/GROOVY_2_4_X Commit: 6c410852b10aca71460ceff321e9839138a53cdc Parents: 5690446 Author: paulk <[email protected]> Authored: Thu Dec 8 16:59:42 2016 +1000 Committer: paulk <[email protected]> Committed: Fri Dec 9 20:04:13 2016 +1000 ---------------------------------------------------------------------- .../groovy/control/OptimizerVisitor.java | 41 ++++++++++++-- .../tools/stubgenerator/Groovy7966Bug.groovy | 58 ++++++++++++++++++++ 2 files changed, 94 insertions(+), 5 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/groovy/blob/6c410852/src/main/org/codehaus/groovy/control/OptimizerVisitor.java ---------------------------------------------------------------------- diff --git a/src/main/org/codehaus/groovy/control/OptimizerVisitor.java b/src/main/org/codehaus/groovy/control/OptimizerVisitor.java index e508d35..6aa0b28 100644 --- a/src/main/org/codehaus/groovy/control/OptimizerVisitor.java +++ b/src/main/org/codehaus/groovy/control/OptimizerVisitor.java @@ -19,6 +19,7 @@ package org.codehaus.groovy.control; import org.codehaus.groovy.ast.ClassCodeExpressionTransformer; +import org.codehaus.groovy.ast.ClassHelper; import org.codehaus.groovy.ast.ClassNode; import org.codehaus.groovy.ast.FieldNode; import org.codehaus.groovy.ast.expr.ClosureExpression; @@ -26,13 +27,18 @@ import org.codehaus.groovy.ast.expr.ConstantExpression; import org.codehaus.groovy.ast.expr.Expression; import org.objectweb.asm.Opcodes; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; /** - * Visitor to produce several optimizations - * - to replace numbered constants with references to static fields - * - * @author Alex Tkachman + * Visitor to produce several optimizations: + * <ul> + * <li>to replace numbered constants with references to static fields</li> + * <li>remove superfluous references to GroovyObject interface</li> + * </ul> */ public class OptimizerVisitor extends ClassCodeExpressionTransformer { private ClassNode currentClass; @@ -51,6 +57,31 @@ public class OptimizerVisitor extends ClassCodeExpressionTransformer { missingFields.clear(); super.visitClass(node); addMissingFields(); + pruneUnneededGroovyObjectInterface(node); + } + + private void pruneUnneededGroovyObjectInterface(ClassNode node) { + ClassNode superClass = node.getSuperClass(); + boolean isSuperGroovy = superClass.isDerivedFromGroovyObject(); + if (isSuperGroovy) { + ClassNode[] interfaces = node.getInterfaces(); + boolean needsFix = false; + for (ClassNode classNode : interfaces) { + if (classNode.equals(ClassHelper.GROOVY_OBJECT_TYPE)) { + needsFix = true; + break; + } + } + if (needsFix) { + List<ClassNode> newInterfaces = new ArrayList<ClassNode>(interfaces.length); + for (ClassNode classNode : interfaces) { + if (!classNode.equals(ClassHelper.GROOVY_OBJECT_TYPE)) { + newInterfaces.add(classNode); + } + } + node.setInterfaces(newInterfaces.toArray(new ClassNode[newInterfaces.size()])); + } + } } private void addMissingFields() { http://git-wip-us.apache.org/repos/asf/groovy/blob/6c410852/src/test/org/codehaus/groovy/tools/stubgenerator/Groovy7966Bug.groovy ---------------------------------------------------------------------- diff --git a/src/test/org/codehaus/groovy/tools/stubgenerator/Groovy7966Bug.groovy b/src/test/org/codehaus/groovy/tools/stubgenerator/Groovy7966Bug.groovy new file mode 100644 index 0000000..acdca6b --- /dev/null +++ b/src/test/org/codehaus/groovy/tools/stubgenerator/Groovy7966Bug.groovy @@ -0,0 +1,58 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.codehaus.groovy.tools.stubgenerator + +/** + * Test that fileorder doesn't impact whether GroovyObject appears in implements list. + */ +class Groovy7966Bug extends StringSourcesStubTestCase { + + @Override + Map<String, String> provideSources() { + [ + 'Before.groovy' : ''' + class Before extends AbstractThing {} + ''', + 'AbstractThing.groovy' : ''' + abstract class AbstractThing {} + ''', + 'JavaThing.java' : ''' + public class JavaThing { + } + ''', + 'After.groovy' : ''' + class After extends AbstractThing {} + ''', + ] + } + + @Override + protected List<File> collectSources(File path) { + // parent method uses order returned by the file system - we want to maintain supplied order + return provideSources().collect{ name, _ -> new File(path, name) } + } + + @Override + void verifyStubs() { + // actually, we don't care about the stubs but let's verify the resulting class files + def classLoader = new URLClassLoader([targetDir.toURI().toURL()] as URL[], loader) + assert classLoader.loadClass('Before').interfaces.length == 0 + assert classLoader.loadClass('After').interfaces.length == 0 + } +}
