Repository: groovy Updated Branches: refs/heads/GROOVY_2_4_X 0a6135b54 -> 369e9826a
GROOVY-7938: inconsistent access of methods in outer class (closes #421) Project: http://git-wip-us.apache.org/repos/asf/groovy/repo Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/369e9826 Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/369e9826 Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/369e9826 Branch: refs/heads/GROOVY_2_4_X Commit: 369e9826aca4f380be419faef74afeb04bfd144c Parents: 0a6135b Author: paulk <pa...@asert.com.au> Authored: Thu Sep 15 19:01:27 2016 +1000 Committer: paulk <pa...@asert.com.au> Committed: Mon Sep 19 11:26:05 2016 +1000 ---------------------------------------------------------------------- .../classgen/InnerClassCompletionVisitor.java | 20 +++++- src/test/groovy/bugs/Groovy7938Bug.groovy | 68 ++++++++++++++++++++ 2 files changed, 87 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/groovy/blob/369e9826/src/main/org/codehaus/groovy/classgen/InnerClassCompletionVisitor.java ---------------------------------------------------------------------- diff --git a/src/main/org/codehaus/groovy/classgen/InnerClassCompletionVisitor.java b/src/main/org/codehaus/groovy/classgen/InnerClassCompletionVisitor.java index 68362a5..de81bdd 100644 --- a/src/main/org/codehaus/groovy/classgen/InnerClassCompletionVisitor.java +++ b/src/main/org/codehaus/groovy/classgen/InnerClassCompletionVisitor.java @@ -177,7 +177,7 @@ public class InnerClassCompletionVisitor extends InnerClassVisitorHelper impleme final String outerClassDescriptor = getTypeDescriptor(outerClass, isStatic); final int objectDistance = getObjectDistance(outerClass); - // add method dispatcher + // add missing method dispatcher Parameter[] parameters = new Parameter[]{ new Parameter(ClassHelper.STRING_TYPE, "name"), new Parameter(ClassHelper.OBJECT_TYPE, "args") @@ -214,6 +214,24 @@ public class InnerClassCompletionVisitor extends InnerClassVisitorHelper impleme } method.setCode(block); + // add static missing method dispatcher + methodName = "$static_methodMissing"; + if (isStatic) + addCompilationErrorOnCustomMethodNode(node, methodName, parameters); + + method = node.addSyntheticMethod( + methodName, + Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, + ClassHelper.OBJECT_TYPE, + parameters, + ClassNode.EMPTY_ARRAY, + null + ); + + block = new BlockStatement(); + setMethodDispatcherCode(block, new ClassExpression(outerClass), parameters); + method.setCode(block); + // add property setter dispatcher parameters = new Parameter[]{ new Parameter(ClassHelper.STRING_TYPE, "name"), http://git-wip-us.apache.org/repos/asf/groovy/blob/369e9826/src/test/groovy/bugs/Groovy7938Bug.groovy ---------------------------------------------------------------------- diff --git a/src/test/groovy/bugs/Groovy7938Bug.groovy b/src/test/groovy/bugs/Groovy7938Bug.groovy new file mode 100644 index 0000000..be7000a --- /dev/null +++ b/src/test/groovy/bugs/Groovy7938Bug.groovy @@ -0,0 +1,68 @@ +/* + * 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 Groovy7938Bug extends GroovyTestCase { + void testClassUsageInInterfaceDef() { + assertScript """ + class Outer { + static Integer fooCount = 0 + Integer barCount = 0 + static void incFoo() { fooCount++ } + void incBar() { barCount++ } + static class Nested { + static void nestedIncFoo() { incFoo() } + static class NestedNested { + static void nestedNestedIncFoo() { incFoo() } + } + } + Inner innerFactory() { new Inner() } + class Inner { + InnerInner innerInnerFactory() { new InnerInner() } + void innerIncFoo() { incFoo() } + static void staticInnerIncFoo() { incFoo() } + class InnerInner { + void innerInnerIncFoo() { incFoo() } + static void staticInnerInnerIncFoo() { incFoo() } + } + } + } + Outer.incFoo() + Outer.Nested.nestedIncFoo() + Outer.Nested.NestedNested.nestedNestedIncFoo() + assert Outer.fooCount == 3 + new Outer().with { + incBar() + incFoo() + innerFactory().with { + incBar() + innerIncFoo() + staticInnerIncFoo() + innerInnerFactory().with { + incBar() + innerInnerIncFoo() + staticInnerInnerIncFoo() + } + } + assert barCount == 3 + assert fooCount == 8 + } + """ + } +}