Repository: groovy Updated Branches: refs/heads/master ad566692d -> 81b1cc7b6
GROOVY-7994: Anonymous inner class believes protected method in parent's superclass returns Object Project: http://git-wip-us.apache.org/repos/asf/groovy/repo Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/81b1cc7b Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/81b1cc7b Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/81b1cc7b Branch: refs/heads/master Commit: 81b1cc7b603659ba58d5f097b73d0f2f1095f8b1 Parents: ad56669 Author: paulk <pa...@asert.com.au> Authored: Thu Nov 10 16:31:46 2016 +1000 Committer: paulk <pa...@asert.com.au> Committed: Fri Nov 11 06:21:39 2016 +1000 ---------------------------------------------------------------------- .../stc/StaticTypeCheckingVisitor.java | 12 +++- src/test/groovy/bugs/Groovy7994Bug.groovy | 69 ++++++++++++++++++++ 2 files changed, 79 insertions(+), 2 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/groovy/blob/81b1cc7b/src/main/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java ---------------------------------------------------------------------- diff --git a/src/main/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java b/src/main/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java index f16ff82..f675526 100644 --- a/src/main/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java +++ b/src/main/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java @@ -1250,9 +1250,9 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport { if (storeField(field, isThisExpression, pexp, receiver.getType(), visitor, receiver.getData(), !readMode)) return true; - MethodNode getter = current.getGetterMethod("get" + capName); + MethodNode getter = findGetter(current, "get" + capName, pexp.isImplicitThis()); getter = allowStaticAccessToMember(getter, staticOnly); - if (getter == null) getter = current.getGetterMethod("is" + capName); + if (getter == null) getter = findGetter(current, "is" + capName, pexp.isImplicitThis()); getter = allowStaticAccessToMember(getter, staticOnly); final String setterName = "set" + capName; List<MethodNode> setters = findSetters(current, setterName, false); @@ -1362,6 +1362,14 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport { return foundGetterOrSetter; } + private MethodNode findGetter(ClassNode current, String name, boolean searchOuterClasses) { + MethodNode getterMethod = current.getGetterMethod(name); + if (getterMethod == null && searchOuterClasses && current instanceof InnerClassNode) { + return findGetter(current.getOuterClass(), name, true); + } + return getterMethod; + } + private ClassNode getTypeForSpreadExpression(ClassNode testClass, ClassNode objectExpressionType, PropertyExpression pexp) { if (!pexp.isSpreadSafe()) return null; MethodCallExpression mce = new MethodCallExpression(new VariableExpression("_", testClass), "iterator", ArgumentListExpression.EMPTY_ARGUMENTS); http://git-wip-us.apache.org/repos/asf/groovy/blob/81b1cc7b/src/test/groovy/bugs/Groovy7994Bug.groovy ---------------------------------------------------------------------- diff --git a/src/test/groovy/bugs/Groovy7994Bug.groovy b/src/test/groovy/bugs/Groovy7994Bug.groovy new file mode 100644 index 0000000..4f4c84a --- /dev/null +++ b/src/test/groovy/bugs/Groovy7994Bug.groovy @@ -0,0 +1,69 @@ +/* + * 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 + +class Groovy7994Bug extends GroovyTestCase { + void testJavaBeanPropertiesAvailableInInnerClasses() { + assertScript ''' + import groovy.transform.CompileStatic + + @CompileStatic + class Outer { + String prop = 'wally' + String getName() { "sally" } + class Inner { + String innerGo() { new Other(name).text + new Other(Outer.this.name).text + new Other(getName()).text } + } + String go() { + new Other(name).text + new Other(getName()).text + } + def makeAIC() { + new Object() { + String aicGo() { new Other(name).text + new Other(Outer.this.name).text + new Other(getName()).text } + String staticMethodGo() { Other.foo(name) + Other.foo(Outer.this.name) + Other.foo(getName()) } + String instanceMethodGo() { new Other().bar(name) + new Other().bar(getName()) } + String methodWithClosureGo() { new Other().with { bar(name) + bar(getName()) } } + String propGo() { new Other(prop).text + new Other(getProp()).text } + } + } + } + + @CompileStatic + class Other { + public final String text + static String foo(Object object) { "Object|$object:" } + static String foo(String string) { "String|$string:" } + String bar(Object object) { "Object|$object:" } + String bar(String string) { "String|$string:" } + Other(Object object) { text = "Object:$object|" } + Other(String string) { text = "String:$string|" } + Other() {} + } + + def o = new Outer() + assert o.go() == 'String:sally|String:sally|' + assert o.makeAIC().aicGo() == 'String:sally|String:sally|String:sally|' + assert o.makeAIC().propGo() == 'String:wally|String:wally|' + assert o.makeAIC().staticMethodGo() == 'String|sally:String|sally:String|sally:' + assert o.makeAIC().instanceMethodGo() == 'String|sally:String|sally:' + assert o.makeAIC().methodWithClosureGo() == 'String|sally:String|sally:' + assert new Outer.Inner(o).innerGo() == 'String:sally|String:sally|String:sally|' + ''' + } +}