This is an automated email from the ASF dual-hosted git repository. emilles pushed a commit to branch GROOVY_2_5_X in repository https://gitbox.apache.org/repos/asf/groovy.git
commit df31b3239aa70da2f234e1cd9eee6d63a2e0fe44 Author: Eric Milles <eric.mil...@thomsonreuters.com> AuthorDate: Fri Feb 18 15:52:27 2022 -0600 GROOVY-9678: check for override of super class property --- .../groovy/classgen/VariableScopeVisitor.java | 14 ++++- src/test/groovy/bugs/Groovy9678.groovy | 73 ++++++++++++++++++++++ 2 files changed, 84 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/codehaus/groovy/classgen/VariableScopeVisitor.java b/src/main/java/org/codehaus/groovy/classgen/VariableScopeVisitor.java index 0dea9d0..6774500 100644 --- a/src/main/java/org/codehaus/groovy/classgen/VariableScopeVisitor.java +++ b/src/main/java/org/codehaus/groovy/classgen/VariableScopeVisitor.java @@ -57,6 +57,7 @@ import java.util.LinkedList; import static java.lang.reflect.Modifier.isFinal; import static java.lang.reflect.Modifier.isStatic; import static org.apache.groovy.ast.tools.MethodNodeUtils.getPropertyName; +import static org.codehaus.groovy.ast.tools.GeneralUtils.getAllProperties; /** * Initializes the variable scopes for an AST. @@ -181,7 +182,12 @@ public class VariableScopeVisitor extends ClassCodeVisitorSupport { for (MethodNode mn : cn.getMethods()) { if ((abstractType || !mn.isAbstract()) && name.equals(getPropertyName(mn))) { - FieldNode fn = new FieldNode(name, mn.getModifiers() & 0xF, ClassHelper.OBJECT_TYPE, cn, null); + // check for override of super class property + for (PropertyNode pn : getAllProperties(cn.getSuperClass())) { + if (name.equals(pn.getName())) return pn; + } + + FieldNode fn = new FieldNode(name, mn.getModifiers() & 0xF, ClassHelper.DYNAMIC_TYPE, cn, null); fn.setHasNoRealSourcePosition(true); fn.setDeclaringClass(cn); fn.setSynthetic(true); @@ -192,9 +198,11 @@ public class VariableScopeVisitor extends ClassCodeVisitorSupport { } } - for (ClassNode face : cn.getAllInterfaces()) { - FieldNode fn = face.getDeclaredField(name); + for (ClassNode in : cn.getAllInterfaces()) { + FieldNode fn = in.getDeclaredField(name); if (fn != null) return fn; + PropertyNode pn = in.getProperty(name); + if (pn != null) return pn; } } diff --git a/src/test/groovy/bugs/Groovy9678.groovy b/src/test/groovy/bugs/Groovy9678.groovy new file mode 100644 index 0000000..b2e9073 --- /dev/null +++ b/src/test/groovy/bugs/Groovy9678.groovy @@ -0,0 +1,73 @@ +/* + * 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 groovy.bugs + +import org.codehaus.groovy.control.CompilerConfiguration +import org.codehaus.groovy.tools.javac.JavaAwareCompilationUnit +import org.junit.Test + +final class Groovy9678 { + + @Test + void testTraitStaticProperty() { + def config = new CompilerConfiguration( + targetDirectory: File.createTempDir(), + jointCompilationOptions: [stubDir: File.createTempDir()] + ) + + def parentDir = File.createTempDir() + try { + def a = new File(parentDir, 'T.groovy') + a.write ''' + trait T { + static p = 1 + } + ''' + def b = new File(parentDir, 'C.groovy') + b.write ''' + class C implements T { + static m() { + p = 2 + p += 1 + return p + } + } + ''' + def c = new File(parentDir, 'Main.java') + c.write ''' + public class Main { + public static void main(String[] args) { + if (!C.m().equals(3)) throw new AssertionError(); + } + } + ''' + + def loader = new GroovyClassLoader(this.class.classLoader) + def cu = new JavaAwareCompilationUnit(config, loader) + cu.addSources(a, b, c) + cu.compile() + + loader.loadClass('Main').main() + } finally { + config.jointCompilationOptions.stubDir.deleteDir() + config.targetDirectory.deleteDir() + parentDir.deleteDir() + } + } +}