You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by su...@apache.org on 2020/07/28 00:04:33 UTC

[groovy] branch GROOVY_3_0_X updated (e06cba7 -> 640e930)

This is an automated email from the ASF dual-hosted git repository.

sunlan pushed a change to branch GROOVY_3_0_X
in repository https://gitbox.apache.org/repos/asf/groovy.git.


    from e06cba7  GROOVY-9658: Infinite recursion exists in HashCodeHelper#updateHash(int, java.lang.Character)
     new 4d04c10  GROOVY-7232: check resolve strategy of each closure during method search
     new 40ee3fd  GROOVY-7304: handle private field access from closure for ++x and x++
     new 640e930  minor fix-ups

The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 src/main/java/groovy/lang/MetaClassImpl.java       | 150 +++++++++++----------
 .../classgen/asm/sc/StaticTypesCallSiteWriter.java |  42 ++++--
 .../groovy/runtime/metaclass/ClosureMetaClass.java |  76 +++++------
 .../transform/sc/StaticCompilationVisitor.java     |  14 +-
 src/test/gls/closures/ResolveStrategyTest.groovy   |  38 +++---
 src/test/groovy/lang/ClosureResolvingTest.groovy   |  41 ++++++
 .../groovy/classgen/asm/sc/bugs/Groovy7276.groovy  |   4 +-
 .../groovy/classgen/asm/sc/bugs/Groovy7304.groovy} |  23 ++--
 8 files changed, 229 insertions(+), 159 deletions(-)
 copy src/test/{groovy/bugs/Groovy9294.groovy => org/codehaus/groovy/classgen/asm/sc/bugs/Groovy7304.groovy} (70%)


[groovy] 02/03: GROOVY-7304: handle private field access from closure for ++x and x++

Posted by su...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

sunlan pushed a commit to branch GROOVY_3_0_X
in repository https://gitbox.apache.org/repos/asf/groovy.git

commit 40ee3fd0c19530b4308c7c1b3e30abd4d45ed54a
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Mon Jul 27 12:34:14 2020 -0500

    GROOVY-7304: handle private field access from closure for ++x and x++
    
    closes #1299
    
    (cherry picked from commit b5c80ae6e66bb2add1722fb1256be490959a7696)
---
 .../classgen/asm/sc/StaticTypesCallSiteWriter.java | 42 ++++++++++++++++------
 .../transform/sc/StaticCompilationVisitor.java     | 14 ++++----
 .../groovy/classgen/asm/sc/bugs/Groovy7276.groovy  |  4 +--
 .../groovy/classgen/asm/sc/bugs/Groovy7304.groovy  | 42 ++++++++++++++++++++++
 4 files changed, 83 insertions(+), 19 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesCallSiteWriter.java b/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesCallSiteWriter.java
index 880c75f..9fe6321 100644
--- a/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesCallSiteWriter.java
+++ b/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesCallSiteWriter.java
@@ -41,6 +41,7 @@ import org.codehaus.groovy.classgen.asm.CompileStack;
 import org.codehaus.groovy.classgen.asm.MethodCallerMultiAdapter;
 import org.codehaus.groovy.classgen.asm.OperandStack;
 import org.codehaus.groovy.classgen.asm.TypeChooser;
+import org.codehaus.groovy.classgen.asm.VariableSlotLoader;
 import org.codehaus.groovy.runtime.InvokerHelper;
 import org.codehaus.groovy.syntax.SyntaxException;
 import org.codehaus.groovy.transform.sc.StaticCompilationMetadataKeys;
@@ -832,14 +833,35 @@ public class StaticTypesCallSiteWriter extends CallSiteWriter implements Opcodes
 
     @Override
     public void fallbackAttributeOrPropertySite(final PropertyExpression expression, final Expression objectExpression, final String name, final MethodCallerMultiAdapter adapter) {
-        if (name != null && (adapter == AsmClassGenerator.setField || adapter == AsmClassGenerator.setGroovyObjectField)) {
-            TypeChooser typeChooser = controller.getTypeChooser();
+        if (name != null && controller.getCompileStack().isLHS()) {
             ClassNode classNode = controller.getClassNode();
-            ClassNode rType = typeChooser.resolveType(objectExpression, classNode);
-            if (controller.getCompileStack().isLHS()) {
-                if (setField(expression, objectExpression, rType, name)) return;
-            } else {
-                if (getField(expression, objectExpression, rType, name)) return;
+            ClassNode receiverType = controller.getTypeChooser().resolveType(objectExpression, classNode);
+            if (adapter == AsmClassGenerator.setField || adapter == AsmClassGenerator.setGroovyObjectField) {
+                if (setField(expression, objectExpression, receiverType, name)) return;
+            } else if (isThisExpression(objectExpression)) {
+                FieldNode fieldNode = receiverType.getField(name);
+                if (fieldNode != null && fieldNode.isPrivate() && !receiverType.equals(classNode)
+                        && StaticInvocationWriter.isPrivateBridgeMethodsCallAllowed(receiverType, classNode)) {
+                    Map<String, MethodNode> mutators = receiverType.redirect().getNodeMetaData(StaticCompilationMetadataKeys.PRIVATE_FIELDS_MUTATORS);
+                    if (mutators != null) {
+                        MethodNode methodNode = mutators.get(name);
+                        if (methodNode != null) {
+                            ClassNode rhsType = controller.getOperandStack().getTopOperand();
+                            int i = controller.getCompileStack().defineTemporaryVariable("$rhsValue", rhsType, true);
+                            VariableSlotLoader rhsValue = new VariableSlotLoader(rhsType, i, controller.getOperandStack());
+
+                            MethodCallExpression call = callX(objectExpression, methodNode.getName(), args(fieldNode.isStatic() ? nullX() : objectExpression, rhsValue));
+                            call.setImplicitThis(expression.isImplicitThis());
+                            call.setSpreadSafe(expression.isSpreadSafe());
+                            call.setSafe(expression.isSafe());
+                            call.setMethodTarget(methodNode);
+                            call.visit(controller.getAcg());
+
+                            controller.getCompileStack().removeVar(i);
+                            return;
+                        }
+                    }
+                }
             }
         }
         super.fallbackAttributeOrPropertySite(expression, objectExpression, name, adapter);
@@ -870,12 +892,10 @@ public class StaticTypesCallSiteWriter extends CallSiteWriter implements Opcodes
             mv.visitFieldInsn(PUTSTATIC, ownerName, name, BytecodeHelper.getTypeDescription(fn.getType()));
         }
 
-        //mv.visitInsn(ACONST_NULL);
-        //stack.replace(OBJECT_TYPE);
         return true;
     }
 
-    private boolean getField(final PropertyExpression expression, final Expression receiver, ClassNode receiverType, final String name) {
+    /*private boolean getField(final PropertyExpression expression, final Expression receiver, ClassNode receiverType, final String name) {
         boolean safe = expression.isSafe();
         boolean implicitThis = expression.isImplicitThis();
 
@@ -898,5 +918,5 @@ public class StaticTypesCallSiteWriter extends CallSiteWriter implements Opcodes
             return true;
         }
         return false;
-    }
+    }*/
 }
diff --git a/src/main/java/org/codehaus/groovy/transform/sc/StaticCompilationVisitor.java b/src/main/java/org/codehaus/groovy/transform/sc/StaticCompilationVisitor.java
index 79fe33a..16c721d 100644
--- a/src/main/java/org/codehaus/groovy/transform/sc/StaticCompilationVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/sc/StaticCompilationVisitor.java
@@ -23,7 +23,6 @@ import groovy.transform.CompileStatic;
 import groovy.transform.TypeChecked;
 import org.codehaus.groovy.ast.ASTNode;
 import org.codehaus.groovy.ast.AnnotatedNode;
-import org.codehaus.groovy.ast.AnnotationNode;
 import org.codehaus.groovy.ast.ClassCodeVisitorSupport;
 import org.codehaus.groovy.ast.ClassHelper;
 import org.codehaus.groovy.ast.ClassNode;
@@ -74,10 +73,12 @@ import static org.codehaus.groovy.ast.ClassHelper.STRING_TYPE;
 import static org.codehaus.groovy.ast.ClassHelper.int_TYPE;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.args;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.assignS;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.attrX;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.callX;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.classX;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.constX;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.ctorThisS;
-import static org.codehaus.groovy.ast.tools.GeneralUtils.propX;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.returnS;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.varX;
 import static org.codehaus.groovy.ast.tools.GenericsUtils.addMethodGenerics;
 import static org.codehaus.groovy.ast.tools.GenericsUtils.applyGenericsContextToPlaceHolders;
@@ -270,19 +271,20 @@ public class StaticCompilationVisitor extends StaticTypeCheckingVisitor {
                 acc += 1;
                 Parameter param = new Parameter(node.getPlainNodeReference(), "$that");
                 Expression receiver = fieldNode.isStatic() ? classX(node) : varX(param);
-                Statement body = new ExpressionStatement(propX(receiver, fieldNode.getName()));
+                Statement body = returnS(attrX(receiver, constX(fieldNode.getName())));
                 MethodNode accessor = node.addMethod("pfaccess$" + acc, modifiers, fieldNode.getOriginType(), new Parameter[]{param}, ClassNode.EMPTY_ARRAY, body);
+                accessor.setNodeMetaData(STATIC_COMPILE_NODE, Boolean.TRUE);
                 privateFieldAccessors.put(fieldNode.getName(), accessor);
             }
-
             if (generateMutator) {
                 // increment acc if it hasn't been incremented in the current iteration
                 if (!generateAccessor) acc += 1;
                 Parameter param = new Parameter(node.getPlainNodeReference(), "$that");
                 Expression receiver = fieldNode.isStatic() ? classX(node) : varX(param);
                 Parameter value = new Parameter(fieldNode.getOriginType(), "$value");
-                Statement body = assignS(propX(receiver, fieldNode.getName()), varX(value));
+                Statement body = assignS(attrX(receiver, constX(fieldNode.getName())), varX(value));
                 MethodNode mutator = node.addMethod("pfaccess$0" + acc, modifiers, fieldNode.getOriginType(), new Parameter[]{param, value}, ClassNode.EMPTY_ARRAY, body);
+                mutator.setNodeMetaData(STATIC_COMPILE_NODE, Boolean.TRUE);
                 privateFieldMutators.put(fieldNode.getName(), mutator);
             }
         }
@@ -375,8 +377,8 @@ public class StaticCompilationVisitor extends StaticTypeCheckingVisitor {
                 if (origGenericsTypes != null) {
                     bridge.setGenericsTypes(applyGenericsContextToPlaceHolders(genericsSpec, origGenericsTypes));
                 }
+                bridge.setNodeMetaData(STATIC_COMPILE_NODE, Boolean.TRUE);
                 privateBridgeMethods.put(method, bridge);
-                bridge.addAnnotation(new AnnotationNode(COMPILESTATIC_CLASSNODE));
             }
         }
         if (!privateBridgeMethods.isEmpty()) {
diff --git a/src/test/org/codehaus/groovy/classgen/asm/sc/bugs/Groovy7276.groovy b/src/test/org/codehaus/groovy/classgen/asm/sc/bugs/Groovy7276.groovy
index a42177c..0cff79c 100644
--- a/src/test/org/codehaus/groovy/classgen/asm/sc/bugs/Groovy7276.groovy
+++ b/src/test/org/codehaus/groovy/classgen/asm/sc/bugs/Groovy7276.groovy
@@ -37,7 +37,7 @@ final class Groovy7276 extends StaticTypeCheckingTestCase implements StaticCompi
     }
 
     void testShouldGoThroughPrivateBridgeMethod2() {
-        ['i'/*, 'i++'*/].each { // GROOVY-7304
+        ['i', 'i++'].each { // GROOVY-7304
             assertScript """
                 class Foo {
                     private int i = 1
@@ -62,7 +62,7 @@ final class Groovy7276 extends StaticTypeCheckingTestCase implements StaticCompi
         }
     }
 
-    @NotYetImplemented // GROOVY-7304
+    // GROOVY-7304
     void testShouldGoThroughPrivateBridgeMethod4() {
         ['++i', 'i+=1', 'i=i+1'].each {
             assertScript """
diff --git a/src/test/org/codehaus/groovy/classgen/asm/sc/bugs/Groovy7304.groovy b/src/test/org/codehaus/groovy/classgen/asm/sc/bugs/Groovy7304.groovy
new file mode 100644
index 0000000..13b5222
--- /dev/null
+++ b/src/test/org/codehaus/groovy/classgen/asm/sc/bugs/Groovy7304.groovy
@@ -0,0 +1,42 @@
+/*
+ *  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.classgen.asm.sc.bugs
+
+import groovy.transform.CompileStatic
+import org.junit.Test
+
+import static groovy.test.GroovyAssert.assertScript
+
+@CompileStatic
+final class Groovy7304 {
+
+    @Test // bridge methods should also be statically compiled
+    void testShouldGoThroughPrivateBridgeMethod() {
+        assertScript '''
+            class A {
+                private int i = 1
+                @groovy.transform.CompileStatic
+                int m() { new String().with { i++ } }
+            }
+            class B extends A {
+            }
+            assert new B().m() == 1
+        '''
+    }
+}


[groovy] 01/03: GROOVY-7232: check resolve strategy of each closure during method search

Posted by su...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

sunlan pushed a commit to branch GROOVY_3_0_X
in repository https://gitbox.apache.org/repos/asf/groovy.git

commit 4d04c10b5d81b7b70352cf9407ba7d664de77fb4
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Mon Jul 27 12:03:20 2020 -0500

    GROOVY-7232: check resolve strategy of each closure during method search
    
    closes #1302
    
    (cherry picked from commit a01d557f05310660f3168a72cfb6635bbd818596)
---
 .../groovy/runtime/metaclass/ClosureMetaClass.java | 76 +++++++++++-----------
 src/test/gls/closures/ResolveStrategyTest.groovy   | 38 +++++------
 src/test/groovy/lang/ClosureResolvingTest.groovy   | 41 ++++++++++++
 3 files changed, 98 insertions(+), 57 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/runtime/metaclass/ClosureMetaClass.java b/src/main/java/org/codehaus/groovy/runtime/metaclass/ClosureMetaClass.java
index af0bf2b..1b97ef9 100644
--- a/src/main/java/org/codehaus/groovy/runtime/metaclass/ClosureMetaClass.java
+++ b/src/main/java/org/codehaus/groovy/runtime/metaclass/ClosureMetaClass.java
@@ -47,7 +47,6 @@ import java.lang.reflect.Constructor;
 import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 
@@ -244,6 +243,7 @@ public final class ClosureMetaClass extends MetaClassImpl {
 
         MetaMethod method = null;
         final Closure closure = (Closure) object;
+        final int resolveStrategy = closure.getResolveStrategy();
 
         if (CLOSURE_DO_CALL_METHOD.equals(methodName) || CLOSURE_CALL_METHOD.equals(methodName)) {
             method = pickClosureMethod(argClasses);
@@ -255,7 +255,7 @@ public final class ClosureMetaClass extends MetaClassImpl {
             if (method == null) throw new MissingMethodException(methodName, theClass, arguments, false);
         }
 
-        boolean shouldDefer = closure.getResolveStrategy() == Closure.DELEGATE_ONLY && isInternalMethod(methodName);
+        boolean shouldDefer = resolveStrategy == Closure.DELEGATE_ONLY && isInternalMethod(methodName);
         if (method == null && !shouldDefer) {
             method = CLOSURE_METACLASS.pickMethod(methodName, argClasses);
         }
@@ -267,7 +267,6 @@ public final class ClosureMetaClass extends MetaClassImpl {
         final Object owner = closure.getOwner();
         final Object delegate = closure.getDelegate();
         final Object thisObject = closure.getThisObject();
-        final int resolveStrategy = closure.getResolveStrategy();
         boolean invokeOnDelegate = false;
         boolean invokeOnOwner = false;
         boolean ownerFirst = true;
@@ -288,48 +287,21 @@ public final class ClosureMetaClass extends MetaClassImpl {
                 if (method == null) {
                     invokeOnOwner = owner != closure && (owner instanceof GroovyObject);
                 }
-
                 break;
-            case Closure.DELEGATE_FIRST:
-                method = getDelegateMethod(closure, delegate, methodName, argClasses);
-                callObject = delegate;
-                if (method == null) {
-                    method = getDelegateMethod(closure, owner, methodName, argClasses);
-                    callObject = owner;
-                }
-                if (method == null) {
-                    invokeOnDelegate = delegate != closure && (delegate instanceof GroovyObject);
-                    invokeOnOwner = owner != closure && (owner instanceof GroovyObject);
-                    ownerFirst = false;
-                }
-                break;
-            default: // owner first
-                // owner first means we start with the outer most owner that is not a generated closure
-                // this owner is equal to the this object, so we check that one first.
-                method = getDelegateMethod(closure, thisObject, methodName, argClasses);
-                callObject = thisObject;
-                if (method == null) {
-                    // try finding a delegate that has that method... we start from
-                    // outside building a stack and try each delegate
-                    LinkedList list = new LinkedList();
-                    for (Object current = closure; current != thisObject;) {
-                        if (!(current instanceof Closure)) break;
-                        Closure currentClosure = (Closure) current;
-                        if (currentClosure.getDelegate() != null) list.add(current);
-                        current = currentClosure.getOwner();
-                    }
-
-                    while (!list.isEmpty() && method == null) {
-                        Closure closureWithDelegate = (Closure) list.removeLast();
-                        Object currentDelegate = closureWithDelegate.getDelegate();
-                        method = getDelegateMethod(closureWithDelegate, currentDelegate, methodName, argClasses);
-                        callObject = currentDelegate;
+            default: // Closure.*_FIRST:
+                for (Object candidate : ownersAndDelegatesOf(closure, new ArrayList<>())) {
+                    method = getDelegateMethod(closure, candidate, methodName, argClasses);
+                    callObject = candidate;
+                    if (method != null) {
+                        break;
                     }
                 }
                 if (method == null) {
                     invokeOnDelegate = delegate != closure && (delegate instanceof GroovyObject);
                     invokeOnOwner = owner != closure && (owner instanceof GroovyObject);
+                    ownerFirst = resolveStrategy != Closure.DELEGATE_FIRST;
                 }
+                break;
         }
         if (method == null && (invokeOnOwner || invokeOnDelegate)) {
             try {
@@ -379,6 +351,34 @@ public final class ClosureMetaClass extends MetaClassImpl {
         return arguments;
     }
 
+    private static List ownersAndDelegatesOf(Closure closure, List ownersAndDelegates) {
+        switch (closure.getResolveStrategy()) {
+        case Closure.TO_SELF:
+            ownersAndDelegates.add(closure);
+            break;
+        case Closure.OWNER_ONLY:
+            ownersAndDelegates.add(closure.getOwner());
+            break;
+        case Closure.DELEGATE_ONLY:
+            ownersAndDelegates.add(closure.getDelegate());
+            break;
+        case Closure.DELEGATE_FIRST:
+            ownersAndDelegates.add(closure.getDelegate());
+            ownersAndDelegates.add(closure.getOwner());
+            if (closure.getOwner() instanceof Closure) {
+                ownersAndDelegatesOf((Closure) closure.getOwner(), ownersAndDelegates);
+            }
+            break;
+        default: // Closure.OWNER_FIRST:
+            ownersAndDelegates.add(closure.getOwner());
+            if (closure.getOwner() instanceof Closure) {
+                ownersAndDelegatesOf((Closure) closure.getOwner(), ownersAndDelegates);
+            }
+            ownersAndDelegates.add(closure.getDelegate());
+        }
+        return ownersAndDelegates;
+    }
+
     private static Throwable unwrap(GroovyRuntimeException gre) {
         Throwable th = gre;
         if (th.getCause() != null && th.getCause() != gre) th = th.getCause();
diff --git a/src/test/gls/closures/ResolveStrategyTest.groovy b/src/test/gls/closures/ResolveStrategyTest.groovy
index e9cb637..1a8111d 100644
--- a/src/test/gls/closures/ResolveStrategyTest.groovy
+++ b/src/test/gls/closures/ResolveStrategyTest.groovy
@@ -20,30 +20,31 @@ package gls.closures
 
 import groovy.test.GroovyTestCase
 import groovy.transform.CompileStatic
+
 import static groovy.lang.Closure.*
 
 class ResolveStrategyTest extends GroovyTestCase {
     void testDynamicSettingOfResolveStrategy() {
         new MyClass().with {
-            assert run(DELEGATE_ONLY) == 12340000 // (*)
-            assert run(DELEGATE_FIRST) == 12040030
             assert run(OWNER_ONLY) == 1234 // (*)
-            assert run(OWNER_FIRST) == 41230
-
-            assert runOwnerOnly { m1() + m2() + m3() } == 1230
             assert runOwnerOnly { m1() + m2() + m3() + m4() } == 1234 // (*)
-            assert runOwnerFirst { m1() + m2() + m3() + m4() } == 41230
+
+            assert run(DELEGATE_ONLY) == 12340000 // (*)
             assert runDelegateOnly { m1() + m2() + m3() + m4() } == 12340000 // (*)
-            assert runDelegateOnly { m1() + m2() + m4() } == 12040000
-            assert runDelegateFirst { m1() + m2() + m3() + m4() } == 12340000 // (**)
+
+            // (*) involves methodMissing as forced by ONLY strategy (no equivalent CS case below)
+
+            assert run(OWNER_FIRST) == 41230
+            assert runOwnerFirst { m1() + m2() + m3() + m4() } == 41230
+
+            assert run(DELEGATE_FIRST) == 12040030
+            assert runDelegateFirst { m1() + m2() + m3() + m4() } == 12040030
 
             // nested cases
-            assert runDelegateFirst { runOwnerFirst { m1() + m2() + m3() + m4() } } == 41230
-            assert runOwnerFirst { runDelegateFirst { m1() + m2() + m3() + m4() } } == 12340000 // (**)
             assert runOwnerFirst { runOwnerFirst { m1() + m2() + m3() + m4() } } == 41230
-            assert runDelegateFirst { runDelegateFirst { m1() + m2() + m3() + m4() } } == 12340000 // (**)
-            // (*) involves methodMissing as forced by ONLY strategy (no equivalent CS case below)
-            // (**) involves methodMissing since delegate methodMissing has precedence over explicit owner method
+            assert runOwnerFirst { runDelegateFirst { m1() + m2() + m3() + m4() } } == 12040030
+            assert runDelegateFirst { runOwnerFirst { m1() + m2() + m3() + m4() } } == 12040030
+            assert runDelegateFirst { runDelegateFirst { m1() + m2() + m3() + m4() } } == 12040030
         }
     }
 
@@ -53,14 +54,13 @@ class ResolveStrategyTest extends GroovyTestCase {
             assert runOwnerOnly { m1() + m2() + m3() } == 1230
             assert runOwnerFirst { m1() + m2() + m3() + m4() } == 41230
             assert runDelegateOnly { m1() + m2() + m4() } == 12040000
-            assert runDelegateFirst { m1() + m2() + m3() + m4() } == 12040030 // (*)
+            assert runDelegateFirst { m1() + m2() + m3() + m4() } == 12040030
 
-            // nested cases (GROOVY-9086)
-            assert runDelegateFirst { runOwnerFirst { m1() + m2() + m3() + m4() } } == 12040030 // (*)
-            assert runOwnerFirst { runDelegateFirst { m1() + m2() + m3() + m4() } } == 12040030 // (*)
+            // GROOVY-9086: nested cases
             assert runOwnerFirst { runOwnerFirst { m1() + m2() + m3() + m4() } } == 41230
-            assert runDelegateFirst { runDelegateFirst { m1() + m2() + m3() + m4() } } == 12040030 // (*)
-            // (*) different to dynamic since static assumes no methodMissing
+            assert runDelegateFirst { runOwnerFirst { m1() + m2() + m3() + m4() } } == 12040030
+            assert runOwnerFirst { runDelegateFirst { m1() + m2() + m3() + m4() } } == 12040030
+            assert runDelegateFirst { runDelegateFirst { m1() + m2() + m3() + m4() } } == 12040030
         }
     }
 }
diff --git a/src/test/groovy/lang/ClosureResolvingTest.groovy b/src/test/groovy/lang/ClosureResolvingTest.groovy
index 69d2932..e266647 100644
--- a/src/test/groovy/lang/ClosureResolvingTest.groovy
+++ b/src/test/groovy/lang/ClosureResolvingTest.groovy
@@ -203,6 +203,47 @@ class ClosureResolvingTest extends GroovyTestCase {
         cout()
     }
 
+    // GROOVY-7232
+    void testOwnerDelegateChain2() {
+        assertScript '''
+            def outer = { ->
+                def inner = { ->
+                    [x, keySet()]
+                }
+                inner.resolveStrategy = Closure.DELEGATE_ONLY
+                inner.delegate = [x: 1, f: 0]
+                inner.call()
+            }
+            //outer.resolveStrategy = Closure.OWNER_FIRST
+            outer.delegate = [x: 0, g: 0]
+            def result = outer.call()
+
+            assert result.flatten() == [1, 'x', 'f']
+        '''
+    }
+
+    // GROOVY-7232
+    void testOwnerDelegateChain3() {
+        assertScript '''
+            def outer = { ->
+                def inner = { ->
+                    def inner_inner = { ->
+                        [x, keySet()]
+                    }
+                    //inner_inner.resolveStrategy = Closure.OWNER_FIRST
+                    return inner_inner.call()
+                }
+                inner.resolveStrategy = Closure.DELEGATE_ONLY
+                inner.delegate = [x: 1, f: 0]
+                inner()
+            }
+            //outer.resolveStrategy = Closure.OWNER_FIRST
+            outer.delegate = [x: 0, g: 0]
+            def result = outer.call()
+
+            assert result.flatten() == [1, 'x', 'f']
+        '''
+    }
 }
 
 class TestResolve1 {


[groovy] 03/03: minor fix-ups

Posted by su...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

sunlan pushed a commit to branch GROOVY_3_0_X
in repository https://gitbox.apache.org/repos/asf/groovy.git

commit 640e9304fe8950400d94adaad474c0c341209df0
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Mon Jul 27 16:09:59 2020 -0500

    minor fix-ups
    
    (cherry picked from commit b6489fd5a6110153fc7bd9ac8a231811ac99cbb7)
---
 src/main/java/groovy/lang/MetaClassImpl.java | 150 ++++++++++++++-------------
 1 file changed, 79 insertions(+), 71 deletions(-)

diff --git a/src/main/java/groovy/lang/MetaClassImpl.java b/src/main/java/groovy/lang/MetaClassImpl.java
index 340941c..59d45e6 100644
--- a/src/main/java/groovy/lang/MetaClassImpl.java
+++ b/src/main/java/groovy/lang/MetaClassImpl.java
@@ -42,6 +42,7 @@ import org.codehaus.groovy.runtime.CurriedClosure;
 import org.codehaus.groovy.runtime.DefaultGroovyMethods;
 import org.codehaus.groovy.runtime.GeneratedClosure;
 import org.codehaus.groovy.runtime.GroovyCategorySupport;
+import org.codehaus.groovy.runtime.GroovyCategorySupport.CategoryMethod;
 import org.codehaus.groovy.runtime.InvokerHelper;
 import org.codehaus.groovy.runtime.InvokerInvocationException;
 import org.codehaus.groovy.runtime.MetaClassHelper;
@@ -81,6 +82,7 @@ import org.codehaus.groovy.vmplugin.VMPlugin;
 import org.codehaus.groovy.vmplugin.VMPluginFactory;
 
 import javax.annotation.Nullable;
+
 import java.beans.BeanInfo;
 import java.beans.EventSetDescriptor;
 import java.beans.Introspector;
@@ -105,6 +107,7 @@ import java.util.Iterator;
 import java.util.LinkedHashSet;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.ListIterator;
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
@@ -180,7 +183,7 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass {
      * @param theClass The class this is the metaclass dor
      * @param add      The methods for this class
      */
-    public MetaClassImpl(final Class theClass, MetaMethod[] add) {
+    public MetaClassImpl(final Class theClass, final MetaMethod[] add) {
         this.theClass = theClass;
         theCachedClass = ReflectionCache.getCachedClass(theClass);
         this.isGroovyObject = GroovyObject.class.isAssignableFrom(theClass);
@@ -213,7 +216,7 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass {
      * @param theClass The class
      * @param add      The methods
      */
-    public MetaClassImpl(MetaClassRegistry registry, final Class theClass, MetaMethod[] add) {
+    public MetaClassImpl(final MetaClassRegistry registry, final Class theClass, final MetaMethod[] add) {
         this(theClass, add);
         this.registry = registry;
         this.constructors = new FastArray(theCachedClass.getConstructors());
@@ -250,7 +253,8 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass {
     /**
      * @see MetaObjectProtocol#respondsTo(Object, String, Object[])
      */
-    public List respondsTo(Object obj, String name, Object[] argTypes) {
+    @Override
+    public List respondsTo(final Object obj, final String name, final Object[] argTypes) {
         Class[] classes = MetaClassHelper.castArgumentsToClassArray(argTypes);
         MetaMethod m = getMetaMethod(name, classes);
         if (m != null) {
@@ -262,6 +266,7 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass {
     /**
      * @see MetaObjectProtocol#respondsTo(Object, String)
      */
+    @Override
     public List respondsTo(final Object obj, final String name) {
         final Object o = getMethods(getTheClass(), name, false);
         if (o instanceof FastArray) {
@@ -273,14 +278,16 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass {
     /**
      * @see MetaObjectProtocol#hasProperty(Object, String)
      */
-    public MetaProperty hasProperty(Object obj, String name) {
+    @Override
+    public MetaProperty hasProperty(final Object obj, final String name) {
         return getMetaProperty(name);
     }
 
     /**
      * @see MetaObjectProtocol#getMetaProperty(String)
      */
-    public MetaProperty getMetaProperty(String name) {
+    @Override
+    public MetaProperty getMetaProperty(final String name) {
         MetaProperty metaProperty = null;
 
         SingleKeyHashMap propertyMap = classPropertyIndex.getNotNull(theCachedClass);
@@ -306,7 +313,8 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass {
     /**
      * @see MetaObjectProtocol#getStaticMetaMethod(String, Object[])
      */
-    public MetaMethod getStaticMetaMethod(String name, Object[] argTypes) {
+    @Override
+    public MetaMethod getStaticMetaMethod(final String name, final Object[] argTypes) {
         Class[] classes = MetaClassHelper.castArgumentsToClassArray(argTypes);
         return pickStaticMethod(name, classes);
     }
@@ -314,7 +322,8 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass {
     /**
      * @see MetaObjectProtocol#getMetaMethod(String, Object[])
      */
-    public MetaMethod getMetaMethod(String name, Object[] argTypes) {
+    @Override
+    public MetaMethod getMetaMethod(final String name, final Object[] argTypes) {
         Class[] classes = MetaClassHelper.castArgumentsToClassArray(argTypes);
         return pickMethod(name, classes);
     }
@@ -361,8 +370,7 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass {
         }
     }
 
-    private void populateMethods(LinkedList<CachedClass> superClasses, CachedClass firstGroovySuper) {
-
+    private void populateMethods(final List<CachedClass> superClasses, final CachedClass firstGroovySuper) {
         MetaMethodIndex.Header header = metaMethodIndex.getHeader(firstGroovySuper.getTheClass());
         CachedClass c;
         Iterator<CachedClass> iter = superClasses.iterator();
@@ -413,20 +421,18 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass {
         }
     }
 
-    private MetaMethod[] getNewMetaMethods(CachedClass c) {
+    private MetaMethod[] getNewMetaMethods(final CachedClass c) {
         if (theCachedClass != c)
             return c.getNewMetaMethods();
 
         return myNewMetaMethods;
     }
 
-    private void addInterfaceMethods(Set<CachedClass> interfaces) {
+    private void addInterfaceMethods(final Set<CachedClass> interfaces) {
         MetaMethodIndex.Header header = metaMethodIndex.getHeader(theClass);
         for (CachedClass c : interfaces) {
-            final CachedMethod[] m = c.getMethods();
-            for (int i = 0; i != m.length; ++i) {
-                MetaMethod method = m[i];
-                addMetaMethodToIndex(method, header);
+            for (CachedMethod m : c.getMethods()) {
+                addMetaMethodToIndex(m, header);
             }
         }
     }
@@ -449,11 +455,13 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass {
 
     private void removeMultimethodsOverloadedWithPrivateMethods() {
         MethodIndexAction mia = new MethodIndexAction() {
-            public boolean skipClass(Class clazz) {
+            @Override
+            public boolean skipClass(final Class<?> clazz) {
                 return clazz == theClass;
             }
 
-            public void methodNameAction(Class clazz, MetaMethodIndex.Entry e) {
+            @Override
+            public void methodNameAction(final Class<?> clazz, final MetaMethodIndex.Entry e) {
                 if (e.methods == null)
                     return;
 
@@ -503,7 +511,7 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass {
             boolean useThis;
 
             @Override
-            public void methodNameAction(Class clazz, MetaMethodIndex.Entry e) {
+            public void methodNameAction(final Class<?> clazz, final MetaMethodIndex.Entry e) {
                 if (useThis) {
                     if (e.methods == null)
                         return;
@@ -552,7 +560,7 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass {
                                     distance = 0;
                                 }
                             }
-                            distance--;
+                            distance -= 1;
                         }
                     }
                 }
@@ -573,10 +581,10 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass {
                 return new String[]{"", "0", mopName};
             }
 
-            private void processFastArray(FastArray methods) {
+            private void processFastArray(final FastArray methods) {
                 final int len = methods.size();
                 final Object[] data = methods.getArray();
-                for (int i = 0; i != len; ++i) {
+                for (int i = 0; i != len; i += 1) {
                     MetaMethod method = (MetaMethod) data[i];
                     if (method instanceof NewMetaMethod) continue;
                     boolean isPrivate = Modifier.isPrivate(method.getModifiers());
@@ -602,22 +610,21 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass {
         iter.iterate();
     }
 
-    private int findMatchingMethod(MetaMethod method, String mopName, int index, CachedMethod[] mopMethods) {
+    private int findMatchingMethod(final MetaMethod method, final String mopName, final int index, final CachedMethod[] mopMethods) {
         int from = index;
         while (from > 0 && mopMethods[from - 1].getName().equals(mopName))
-            from--;
+            from -= 1;
         int to = index;
         while (to < mopMethods.length - 1 && mopMethods[to + 1].getName().equals(mopName))
-            to++;
+            to += 1;
 
         return findMatchingMethod(mopMethods, from, to, method);
     }
 
-    private void inheritInterfaceNewMetaMethods(Set<CachedClass> interfaces) {
+    private void inheritInterfaceNewMetaMethods(final Set<CachedClass> interfaces) {
         // add methods declared by DGM for interfaces
-        for (CachedClass cls : interfaces) {
-            MetaMethod[] methods = getNewMetaMethods(cls);
-            for (MetaMethod method : methods) {
+        for (CachedClass face : interfaces) {
+            for (MetaMethod method : getNewMetaMethods(face)) {
                 boolean skip = false;
                 // skip DGM methods on an interface if the class already has the method
                 // but don't skip for GroovyObject-related methods as it breaks things :-(
@@ -640,10 +647,11 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass {
         }
     }
 
-    private void connectMultimethods(List<CachedClass> superClasses, CachedClass firstGroovyClass) {
-        superClasses = DefaultGroovyMethods.reverse(superClasses);
+    private void connectMultimethods(final List<CachedClass> superClasses, final CachedClass firstGroovyClass) {
         MetaMethodIndex.Header last = null;
-        for (final CachedClass c : superClasses) {
+        for (ListIterator<CachedClass> iter = superClasses.listIterator(superClasses.size()); iter.hasPrevious(); ) {
+            CachedClass c = iter.previous();
+
             MetaMethodIndex.Header methodIndex = metaMethodIndex.getHeader(c.getTheClass());
             // We don't copy DGM methods to superclasses' indexes
             // The reason we can do that is particular set of DGM methods in use,
@@ -658,14 +666,14 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass {
         }
     }
 
-    private CachedClass calcFirstGroovySuperClass(Collection superClasses) {
+    private CachedClass calcFirstGroovySuperClass(final List<CachedClass> superClasses) {
         if (theCachedClass.isInterface)
             return ReflectionCache.OBJECT_CLASS;
 
         CachedClass firstGroovy = null;
-        Iterator iter = superClasses.iterator();
+        Iterator<CachedClass> iter = superClasses.iterator();
         while (iter.hasNext()) {
-            CachedClass c = (CachedClass) iter.next();
+            CachedClass c = iter.next();
             if (GroovyObject.class.isAssignableFrom(c.getTheClass())) {
                 firstGroovy = c;
                 break;
@@ -674,12 +682,10 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass {
 
         if (firstGroovy == null) {
             firstGroovy = theCachedClass;
-        } else {
-            if (firstGroovy.getTheClass() == GroovyObjectSupport.class && iter.hasNext()) {
-                firstGroovy = (CachedClass) iter.next();
-                if (firstGroovy.getTheClass() == Closure.class && iter.hasNext()) {
-                    firstGroovy = (CachedClass) iter.next();
-                }
+        } else if (firstGroovy.getTheClass() == GroovyObjectSupport.class && iter.hasNext()) {
+            firstGroovy = iter.next();
+            if (firstGroovy.getTheClass() == Closure.class && iter.hasNext()) {
+                firstGroovy = iter.next();
             }
         }
 
@@ -692,7 +698,7 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass {
      * @return all the normal instance methods available on this class for the
      * given name
      */
-    private Object getMethods(Class sender, String name, boolean isCallToSuper) {
+    private Object getMethods(final Class<?> sender, final String name, final boolean isCallToSuper) {
         Object answer;
 
         final MetaMethodIndex.Entry entry = metaMethodIndex.getMethods(sender, name);
@@ -707,7 +713,7 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass {
         if (answer == null) answer = FastArray.EMPTY_LIST;
 
         if (!isCallToSuper) {
-            List used = GroovyCategorySupport.getCategoryMethods(name);
+            List<CategoryMethod> used = GroovyCategorySupport.getCategoryMethods(name);
             if (used != null) {
                 FastArray arr;
                 if (answer instanceof MetaMethod) {
@@ -716,11 +722,10 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass {
                 } else {
                     arr = ((FastArray) answer).copy();
                 }
-                for (Object o : used) {
-                    MetaMethod element = (MetaMethod) o;
-                    if (!element.getDeclaringClass().getTheClass().isAssignableFrom(sender))
+                for (CategoryMethod cm : used) {
+                    if (!cm.getDeclaringClass().getTheClass().isAssignableFrom(sender))
                         continue;
-                    filterMatchingMethodForCategory(arr, element);
+                    filterMatchingMethodForCategory(arr, cm);
                 }
                 answer = arr;
             }
@@ -734,7 +739,7 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass {
      * @return all the normal static methods available on this class for the
      * given name
      */
-    private Object getStaticMethods(Class sender, String name) {
+    private Object getStaticMethods(final Class<?> sender, final String name) {
         final MetaMethodIndex.Entry entry = metaMethodIndex.getMethods(sender, name);
         if (entry == null)
             return FastArray.EMPTY_LIST;
@@ -750,6 +755,7 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass {
      *
      * @return false
      */
+    @Override
     public boolean isModified() {
         return false;  // MetaClassImpl not designed for modification, just return false
     }
@@ -759,14 +765,14 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass {
      *
      * @param method The method to be added
      */
-    public void addNewInstanceMethod(Method method) {
-        final CachedMethod cachedMethod = CachedMethod.find(method);
+    @Override
+    public void addNewInstanceMethod(final Method method) {
+        CachedMethod cachedMethod = CachedMethod.find(method);
         NewInstanceMetaMethod newMethod = new NewInstanceMetaMethod(cachedMethod);
-        final CachedClass declaringClass = newMethod.getDeclaringClass();
-        addNewInstanceMethodToIndex(newMethod, metaMethodIndex.getHeader(declaringClass.getTheClass()));
+        addNewInstanceMethodToIndex(newMethod, metaMethodIndex.getHeader(newMethod.getDeclaringClass().getTheClass()));
     }
 
-    private void addNewInstanceMethodToIndex(MetaMethod newMethod, MetaMethodIndex.Header header) {
+    private void addNewInstanceMethodToIndex(final MetaMethod newMethod, final MetaMethodIndex.Header header) {
         if (!newGroovyMethodsSet.contains(newMethod)) {
             newGroovyMethodsSet.add(newMethod);
             addMetaMethodToIndex(newMethod, header);
@@ -778,14 +784,14 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass {
      *
      * @param method The method to be added
      */
-    public void addNewStaticMethod(Method method) {
-        final CachedMethod cachedMethod = CachedMethod.find(method);
+    @Override
+    public void addNewStaticMethod(final Method method) {
+        CachedMethod cachedMethod = CachedMethod.find(method);
         NewStaticMetaMethod newMethod = new NewStaticMetaMethod(cachedMethod);
-        final CachedClass declaringClass = newMethod.getDeclaringClass();
-        addNewStaticMethodToIndex(newMethod, metaMethodIndex.getHeader(declaringClass.getTheClass()));
+        addNewStaticMethodToIndex(newMethod, metaMethodIndex.getHeader(newMethod.getDeclaringClass().getTheClass()));
     }
 
-    private void addNewStaticMethodToIndex(MetaMethod newMethod, MetaMethodIndex.Header header) {
+    private void addNewStaticMethodToIndex(final MetaMethod newMethod, final MetaMethodIndex.Header header) {
         if (!newGroovyMethodsSet.contains(newMethod)) {
             newGroovyMethodsSet.add(newMethod);
             addMetaMethodToIndex(newMethod, header);
@@ -800,13 +806,13 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass {
      * @param arguments  The arguments to the invoked method as null, a Tuple, an array or a single argument of any type.
      * @return The result of the method invocation.
      */
-    public Object invokeMethod(Object object, String methodName, Object arguments) {
+    @Override
+    public Object invokeMethod(final Object object, final String methodName, final Object arguments) {
         if (arguments == null) {
             return invokeMethod(object, methodName, MetaClassHelper.EMPTY_ARRAY);
         }
         if (arguments instanceof Tuple) {
-            Tuple tuple = (Tuple) arguments;
-            return invokeMethod(object, methodName, tuple.toArray());
+            return invokeMethod(object, methodName, ((Tuple<?>) arguments).toArray());
         }
         if (arguments instanceof Object[]) {
             return invokeMethod(object, methodName, (Object[]) arguments);
@@ -822,7 +828,8 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass {
      * @param arguments  The arguments to the invoked method.
      * @return The result of the method invocation.
      */
-    public Object invokeMissingMethod(Object instance, String methodName, Object[] arguments) {
+    @Override
+    public Object invokeMissingMethod(final Object instance, final String methodName, final Object[] arguments) {
         return invokeMissingMethod(instance, methodName, arguments, null, false);
     }
 
@@ -835,7 +842,8 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass {
      * @param isGetter      Whether the method is a getter
      * @return The result of the method invocation.
      */
-    public Object invokeMissingProperty(Object instance, String propertyName, Object optionalValue, boolean isGetter) {
+    @Override
+    public Object invokeMissingProperty(final Object instance, final String propertyName, final Object optionalValue, final boolean isGetter) {
         MetaBeanProperty property = findPropertyInClassHierarchy(propertyName, theCachedClass);
         if (property != null) {
             onSuperPropertyFoundInHierarchy(property);
@@ -848,14 +856,14 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass {
 
         // look for getProperty or setProperty overrides
         if (isGetter) {
-            final Class[] getPropertyArgs = {String.class};
+            final Class<?>[] getPropertyArgs = {String.class};
             final MetaMethod method = findMethodInClassHierarchy(instance.getClass(), GET_PROPERTY_METHOD, getPropertyArgs, this);
             if (method instanceof ClosureMetaMethod) {
                 onGetPropertyFoundInHierarchy(method);
                 return method.invoke(instance, new Object[]{propertyName});
             }
         } else {
-            final Class[] setPropertyArgs = {String.class, Object.class};
+            final Class<?>[] setPropertyArgs = {String.class, Object.class};
             final MetaMethod method = findMethodInClassHierarchy(instance.getClass(), SET_PROPERTY_METHOD, setPropertyArgs, this);
             if (method instanceof ClosureMetaMethod) {
                 onSetPropertyFoundInHierarchy(method);
@@ -884,7 +892,7 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass {
             throw iie;
         }
 
-        Class theClass = instance instanceof Class ? (Class) instance : instance.getClass();
+        Class<?> theClass = instance instanceof Class ? (Class<?>) instance : instance.getClass();
         if (instance instanceof Class && theClass != Class.class) {
             final MetaProperty metaProperty = InvokerHelper.getMetaClass(Class.class).hasProperty(instance, propertyName);
             if (metaProperty != null) {
@@ -899,17 +907,17 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass {
         throw new MissingPropertyExceptionNoStack(propertyName, theClass);
     }
 
-    private Object invokeMissingMethod(Object instance, String methodName, Object[] arguments, RuntimeException original, boolean isCallToSuper) {
+    private Object invokeMissingMethod(final Object instance, final String methodName, final Object[] arguments, final RuntimeException original, final boolean isCallToSuper) {
         if (isCallToSuper) {
             MetaClass metaClass = InvokerHelper.getMetaClass(theClass.getSuperclass());
             return metaClass.invokeMissingMethod(instance, methodName, arguments);
         }
 
-        Class instanceKlazz = instance.getClass();
+        Class<?> instanceKlazz = instance.getClass();
         if (theClass != instanceKlazz && theClass.isAssignableFrom(instanceKlazz))
             instanceKlazz = theClass;
 
-        Class[] argClasses = MetaClassHelper.castArgumentsToClassArray(arguments);
+        Class<?>[] argClasses = MetaClassHelper.castArgumentsToClassArray(arguments);
 
         MetaMethod method = findMixinMethod(methodName, argClasses);
         if (method != null) {
@@ -924,7 +932,7 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass {
         }
 
         // still not method here, so see if there is an invokeMethod method up the hierarchy
-        final Class[] invokeMethodArgs = {String.class, Object[].class};
+        final Class<?>[] invokeMethodArgs = {String.class, Object[].class};
         method = findMethodInClassHierarchy(instanceKlazz, INVOKE_METHOD_METHOD, invokeMethodArgs, this);
         if (method instanceof ClosureMetaMethod) {
             onInvokeMethodFoundInHierarchy(method);
@@ -3834,9 +3842,9 @@ public class MetaClassImpl implements MetaClass, MutableMetaClass {
             }
         }
 
-        public abstract void methodNameAction(Class clazz, MetaMethodIndex.Entry methods);
+        public abstract void methodNameAction(Class<?> clazz, MetaMethodIndex.Entry methods);
 
-        public boolean skipClass(Class clazz) {
+        public boolean skipClass(final Class<?> clazz) {
             return false;
         }
     }