You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by pa...@apache.org on 2016/06/01 03:43:38 UTC

[1/2] groovy git commit: GROOVY-7620: No error if abstract getter is not implemented but static field exists (closes #342)

Repository: groovy
Updated Branches:
  refs/heads/master 4738970c6 -> 3d60dbd79


GROOVY-7620: No error if abstract getter is not implemented but static field exists (closes #342)


Project: http://git-wip-us.apache.org/repos/asf/groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/973197fd
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/973197fd
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/973197fd

Branch: refs/heads/master
Commit: 973197fdb5e27df579f5ae9b918d3fa13213f482
Parents: 4738970
Author: paulk <pa...@asert.com.au>
Authored: Tue May 31 21:14:54 2016 +1000
Committer: paulk <pa...@asert.com.au>
Committed: Wed Jun 1 13:20:06 2016 +1000

----------------------------------------------------------------------
 src/main/org/codehaus/groovy/ast/ClassNode.java | 23 ++++---
 .../classgen/ClassCompletionVerifier.java       | 71 +++++++++++---------
 src/test/groovy/bugs/Groovy7081Bug.groovy       |  2 +-
 src/test/groovy/bugs/Groovy7620Bug.groovy       | 59 ++++++++++++++++
 4 files changed, 114 insertions(+), 41 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/973197fd/src/main/org/codehaus/groovy/ast/ClassNode.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/ast/ClassNode.java b/src/main/org/codehaus/groovy/ast/ClassNode.java
index 6601ac7..68ac22d 100644
--- a/src/main/org/codehaus/groovy/ast/ClassNode.java
+++ b/src/main/org/codehaus/groovy/ast/ClassNode.java
@@ -425,30 +425,33 @@ public class ClassNode extends AnnotatedNode implements Opcodes {
     public Map<String, MethodNode> getDeclaredMethodsMap() {
         // Start off with the methods from the superclass.
         ClassNode parent = getSuperClass();
-        Map<String, MethodNode> result = null;
+        Map<String, MethodNode> result;
         if (parent != null) {
             result = parent.getDeclaredMethodsMap();
         } else {
             result = new HashMap<String, MethodNode>();
         }
+        addInterfaceMethods(result);
 
+        // And add in the methods implemented in this class.
+        for (MethodNode method : getMethods()) {
+            String sig = method.getTypeDescriptor();
+            result.put(sig, method);
+        }
+        return result;
+    }
+
+    public void addInterfaceMethods(Map<String, MethodNode> methodsMap) {
         // add in unimplemented abstract methods from the interfaces
         for (ClassNode iface : getInterfaces()) {
             Map<String, MethodNode> ifaceMethodsMap = iface.getDeclaredMethodsMap();
             for (String methSig : ifaceMethodsMap.keySet()) {
-                if (!result.containsKey(methSig)) {
+                if (!methodsMap.containsKey(methSig)) {
                     MethodNode methNode = ifaceMethodsMap.get(methSig);
-                    result.put(methSig, methNode);
+                    methodsMap.put(methSig, methNode);
                 }
             }
         }
-
-        // And add in the methods implemented in this class.
-        for (MethodNode method : getMethods()) {
-            String sig = method.getTypeDescriptor();
-            result.put(sig, method);
-        }
-        return result;
     }
 
     public String getName() {

http://git-wip-us.apache.org/repos/asf/groovy/blob/973197fd/src/main/org/codehaus/groovy/classgen/ClassCompletionVerifier.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/classgen/ClassCompletionVerifier.java b/src/main/org/codehaus/groovy/classgen/ClassCompletionVerifier.java
index 47e3175..c29c705 100644
--- a/src/main/org/codehaus/groovy/classgen/ClassCompletionVerifier.java
+++ b/src/main/org/codehaus/groovy/classgen/ClassCompletionVerifier.java
@@ -84,33 +84,48 @@ public class ClassCompletionVerifier extends ClassCodeVisitorSupport {
     }
 
     private void checkNoStaticMethodWithSameSignatureAsNonStatic(final ClassNode node) {
-        Map<String, MethodNode> result = new HashMap<String, MethodNode>();
-        // add in unimplemented abstract methods from the interfaces
-        for (ClassNode iface : node.getInterfaces()) {
-            Map<String, MethodNode> ifaceMethodsMap = iface.getDeclaredMethodsMap();
-            for (String methSig : ifaceMethodsMap.keySet()) {
-                if (!result.containsKey(methSig)) {
-                    MethodNode methNode = ifaceMethodsMap.get(methSig);
-                    result.put(methSig, methNode);
-                }
-            }
+        ClassNode parent = node.getSuperClass();
+        Map<String, MethodNode> result;
+        // start with methods from the parent if any
+        if (parent != null) {
+            result = parent.getDeclaredMethodsMap();
+        } else {
+            result = new HashMap<String, MethodNode>();
         }
+        // add in unimplemented abstract methods from the interfaces
+        node.addInterfaceMethods(result);
         for (MethodNode methodNode : node.getMethods()) {
             MethodNode mn = result.get(methodNode.getTypeDescriptor());
-            if (mn!=null && methodNode.isStatic() && !methodNode.isStaticConstructor()) {
+            if (mn != null && (mn.isStatic() ^ methodNode.isStatic()) && !methodNode.isStaticConstructor()) {
+                if (!mn.isAbstract()) continue;
                 ClassNode declaringClass = mn.getDeclaringClass();
                 ClassNode cn = declaringClass.getOuterClass();
-                if (cn==null && declaringClass.isResolved()) {
+                if (cn == null && declaringClass.isResolved()) {
                     // in case of a precompiled class, the outerclass is unknown
                     Class typeClass = declaringClass.getTypeClass();
                     typeClass = typeClass.getEnclosingClass();
-                    if (typeClass!=null) {
+                    if (typeClass != null) {
                         cn = ClassHelper.make(typeClass);
                     }
                 }
-                if (cn==null || !Traits.isTrait(cn)) {
-                    addError("Method '" + mn.getName() + "' is already defined in " + getDescription(node) + ". You cannot have " +
-                            "both a static and a non static method with the same signature", methodNode);
+                if (cn == null || !Traits.isTrait(cn)) {
+                    ASTNode errorNode = methodNode;
+                    String name = mn.getName();
+                    if (errorNode.getLineNumber() == -1) {
+                        // try to get a better error message location based on the property
+                        for (PropertyNode propertyNode : node.getProperties()) {
+                            if (name.startsWith("set") || name.startsWith("get") || name.startsWith("is")) {
+                                String propName = Verifier.capitalize(propertyNode.getField().getName());
+                                String shortName = name.substring(name.startsWith("is") ? 2 : 3);
+                                if (propName.equals(shortName)) {
+                                    errorNode = propertyNode;
+                                    break;
+                                }
+                            }
+                        }
+                    }
+                    addError("The " + getDescription(methodNode) + " is already defined in " + getDescription(node) +
+                            ". You cannot have both a static and an instance method with the same signature", errorNode);
                 }
             }
             result.put(methodNode.getTypeDescriptor(), methodNode);
@@ -307,6 +322,13 @@ public class ClassCompletionVerifier extends ClassCodeVisitorSupport {
     private void addInvalidUseOfFinalError(MethodNode method, Parameter[] parameters, ClassNode superCN) {
         StringBuilder msg = new StringBuilder();
         msg.append("You are not allowed to override the final method ").append(method.getName());
+        appendParamsDescription(parameters, msg);
+        msg.append(" from ").append(getDescription(superCN));
+        msg.append(".");
+        addError(msg.toString(), method);
+    }
+
+    private void appendParamsDescription(Parameter[] parameters, StringBuilder msg) {
         msg.append("(");
         boolean needsComma = false;
         for (Parameter parameter : parameters) {
@@ -317,25 +339,14 @@ public class ClassCompletionVerifier extends ClassCodeVisitorSupport {
             }
             msg.append(parameter.getType());
         }
-        msg.append(") from ").append(getDescription(superCN));
-        msg.append(".");
-        addError(msg.toString(), method);
+        msg.append(")");
     }
 
     private void addWeakerAccessError(ClassNode cn, MethodNode method, Parameter[] parameters, MethodNode superMethod) {
         StringBuilder msg = new StringBuilder();
         msg.append(method.getName());
-        msg.append("(");
-        boolean needsComma = false;
-        for (Parameter parameter : parameters) {
-            if (needsComma) {
-                msg.append(",");
-            } else {
-                needsComma = true;
-            }
-            msg.append(parameter.getType());
-        }
-        msg.append(") in ");
+        appendParamsDescription(parameters, msg);
+        msg.append(" in ");
         msg.append(cn.getName());
         msg.append(" cannot override ");
         msg.append(superMethod.getName());

http://git-wip-us.apache.org/repos/asf/groovy/blob/973197fd/src/test/groovy/bugs/Groovy7081Bug.groovy
----------------------------------------------------------------------
diff --git a/src/test/groovy/bugs/Groovy7081Bug.groovy b/src/test/groovy/bugs/Groovy7081Bug.groovy
index ba6c44e..1415318 100644
--- a/src/test/groovy/bugs/Groovy7081Bug.groovy
+++ b/src/test/groovy/bugs/Groovy7081Bug.groovy
@@ -31,7 +31,7 @@ class Groovy7081Bug extends GroovyTestCase {
             new Foo().name
             '''
 
-        assert msg.contains("Method 'getName' is already defined in class 'Foo'")
+        assert msg.contains("The method 'java.lang.String getName()' is already defined in class 'Foo'")
     }
 
     void testShouldSeeConflictInTypeSignature() {

http://git-wip-us.apache.org/repos/asf/groovy/blob/973197fd/src/test/groovy/bugs/Groovy7620Bug.groovy
----------------------------------------------------------------------
diff --git a/src/test/groovy/bugs/Groovy7620Bug.groovy b/src/test/groovy/bugs/Groovy7620Bug.groovy
new file mode 100644
index 0000000..44525ef
--- /dev/null
+++ b/src/test/groovy/bugs/Groovy7620Bug.groovy
@@ -0,0 +1,59 @@
+/*
+ * 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 Groovy7620Bug extends GroovyTestCase {
+    void testShouldSeeThatMethodIsNotImplemented() {
+        def msg = shouldFail '''
+            abstract class A {
+               abstract Object getFoo()
+
+               void test() {
+                   println getFoo()
+               }
+            }
+
+            class B extends A {
+               static Object foo
+            }
+
+            new B().test()
+            '''
+
+        assert msg.contains("The method 'java.lang.Object getFoo()' is already defined in class 'B'")
+    }
+
+    void testShouldSeeConflictInTypeSignature() {
+        def msg = shouldFail '''
+            interface C {
+               Object getFoo()
+            }
+
+            class D implements C {
+               static Object foo
+            }
+
+            new B().test()
+            '''
+
+        assert msg.contains("The method 'java.lang.Object getFoo()' is already defined in class 'D'")
+    }
+}


[2/2] groovy git commit: minor refactor

Posted by pa...@apache.org.
minor refactor


Project: http://git-wip-us.apache.org/repos/asf/groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/3d60dbd7
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/3d60dbd7
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/3d60dbd7

Branch: refs/heads/master
Commit: 3d60dbd796c6b362c8c590b14c247b9769a8edbf
Parents: 973197f
Author: paulk <pa...@asert.com.au>
Authored: Wed Jun 1 13:35:39 2016 +1000
Committer: paulk <pa...@asert.com.au>
Committed: Wed Jun 1 13:35:39 2016 +1000

----------------------------------------------------------------------
 src/main/org/codehaus/groovy/ast/ClassNode.java | 29 ++------------
 .../groovy/ast/tools/ClassNodeUtils.java        | 41 ++++++++++++++++++++
 .../groovy/ast/tools/ParameterUtils.java        | 39 +++++++++++++++++++
 .../classgen/ClassCompletionVerifier.java       |  3 +-
 .../groovy/classgen/ExtendedVerifier.java       | 19 +--------
 .../classgen/asm/OptimizingStatementWriter.java | 18 +--------
 6 files changed, 90 insertions(+), 59 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/3d60dbd7/src/main/org/codehaus/groovy/ast/ClassNode.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/ast/ClassNode.java b/src/main/org/codehaus/groovy/ast/ClassNode.java
index 68ac22d..37ad787 100644
--- a/src/main/org/codehaus/groovy/ast/ClassNode.java
+++ b/src/main/org/codehaus/groovy/ast/ClassNode.java
@@ -23,6 +23,8 @@ import org.codehaus.groovy.ast.expr.*;
 import org.codehaus.groovy.ast.stmt.BlockStatement;
 import org.codehaus.groovy.ast.stmt.ExpressionStatement;
 import org.codehaus.groovy.ast.stmt.Statement;
+import org.codehaus.groovy.ast.tools.ClassNodeUtils;
+import org.codehaus.groovy.ast.tools.ParameterUtils;
 import org.codehaus.groovy.control.CompilePhase;
 import org.codehaus.groovy.transform.ASTTransformation;
 import org.codehaus.groovy.transform.GroovyASTTransformation;
@@ -431,7 +433,7 @@ public class ClassNode extends AnnotatedNode implements Opcodes {
         } else {
             result = new HashMap<String, MethodNode>();
         }
-        addInterfaceMethods(result);
+        ClassNodeUtils.addInterfaceMethods(this, result);
 
         // And add in the methods implemented in this class.
         for (MethodNode method : getMethods()) {
@@ -441,19 +443,6 @@ public class ClassNode extends AnnotatedNode implements Opcodes {
         return result;
     }
 
-    public void addInterfaceMethods(Map<String, MethodNode> methodsMap) {
-        // add in unimplemented abstract methods from the interfaces
-        for (ClassNode iface : getInterfaces()) {
-            Map<String, MethodNode> ifaceMethodsMap = iface.getDeclaredMethodsMap();
-            for (String methSig : ifaceMethodsMap.keySet()) {
-                if (!methodsMap.containsKey(methSig)) {
-                    MethodNode methNode = ifaceMethodsMap.get(methSig);
-                    methodsMap.put(methSig, methNode);
-                }
-            }
-        }
-    }
-
     public String getName() {
         return redirect().name;
     }
@@ -1047,17 +1036,7 @@ public class ClassNode extends AnnotatedNode implements Opcodes {
      * @return true if the two arrays are of the same size and have the same contents
      */
     protected boolean parametersEqual(Parameter[] a, Parameter[] b) {
-        if (a.length == b.length) {
-            boolean answer = true;
-            for (int i = 0; i < a.length; i++) {
-                if (!a[i].getType().equals(b[i].getType())) {
-                    answer = false;
-                    break;
-                }
-            }
-            return answer;
-        }
-        return false;
+        return ParameterUtils.parametersEqual(a, b);
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/groovy/blob/3d60dbd7/src/main/org/codehaus/groovy/ast/tools/ClassNodeUtils.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/ast/tools/ClassNodeUtils.java b/src/main/org/codehaus/groovy/ast/tools/ClassNodeUtils.java
new file mode 100644
index 0000000..f3eec90
--- /dev/null
+++ b/src/main/org/codehaus/groovy/ast/tools/ClassNodeUtils.java
@@ -0,0 +1,41 @@
+/*
+ * 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.ast.tools;
+
+import org.codehaus.groovy.ast.ClassNode;
+import org.codehaus.groovy.ast.MethodNode;
+
+import java.util.Map;
+
+public class ClassNodeUtils {
+    public static void addInterfaceMethods(ClassNode cnode, Map<String, MethodNode> methodsMap) {
+        // add in unimplemented abstract methods from the interfaces
+        for (ClassNode iface : cnode.getInterfaces()) {
+            Map<String, MethodNode> ifaceMethodsMap = iface.getDeclaredMethodsMap();
+            for (String methSig : ifaceMethodsMap.keySet()) {
+                if (!methodsMap.containsKey(methSig)) {
+                    MethodNode methNode = ifaceMethodsMap.get(methSig);
+                    methodsMap.put(methSig, methNode);
+                }
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/3d60dbd7/src/main/org/codehaus/groovy/ast/tools/ParameterUtils.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/ast/tools/ParameterUtils.java b/src/main/org/codehaus/groovy/ast/tools/ParameterUtils.java
new file mode 100644
index 0000000..4edf92e
--- /dev/null
+++ b/src/main/org/codehaus/groovy/ast/tools/ParameterUtils.java
@@ -0,0 +1,39 @@
+/*
+ * 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.ast.tools;
+
+import org.codehaus.groovy.ast.Parameter;
+
+public class ParameterUtils {
+    public static boolean parametersEqual(Parameter[] a, Parameter[] b) {
+        if (a.length == b.length) {
+            boolean answer = true;
+            for (int i = 0; i < a.length; i++) {
+                if (!a[i].getType().equals(b[i].getType())) {
+                    answer = false;
+                    break;
+                }
+            }
+            return answer;
+        }
+        return false;
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/3d60dbd7/src/main/org/codehaus/groovy/classgen/ClassCompletionVerifier.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/classgen/ClassCompletionVerifier.java b/src/main/org/codehaus/groovy/classgen/ClassCompletionVerifier.java
index c29c705..9fe13cf 100644
--- a/src/main/org/codehaus/groovy/classgen/ClassCompletionVerifier.java
+++ b/src/main/org/codehaus/groovy/classgen/ClassCompletionVerifier.java
@@ -35,6 +35,7 @@ import org.codehaus.groovy.ast.expr.PropertyExpression;
 import org.codehaus.groovy.ast.expr.TupleExpression;
 import org.codehaus.groovy.ast.expr.VariableExpression;
 import org.codehaus.groovy.ast.stmt.CatchStatement;
+import org.codehaus.groovy.ast.tools.ClassNodeUtils;
 import org.codehaus.groovy.ast.tools.GeneralUtils;
 import org.codehaus.groovy.control.SourceUnit;
 import org.codehaus.groovy.runtime.MetaClassHelper;
@@ -93,7 +94,7 @@ public class ClassCompletionVerifier extends ClassCodeVisitorSupport {
             result = new HashMap<String, MethodNode>();
         }
         // add in unimplemented abstract methods from the interfaces
-        node.addInterfaceMethods(result);
+        ClassNodeUtils.addInterfaceMethods(node, result);
         for (MethodNode methodNode : node.getMethods()) {
             MethodNode mn = result.get(methodNode.getTypeDescriptor());
             if (mn != null && (mn.isStatic() ^ methodNode.isStatic()) && !methodNode.isStaticConstructor()) {

http://git-wip-us.apache.org/repos/asf/groovy/blob/3d60dbd7/src/main/org/codehaus/groovy/classgen/ExtendedVerifier.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/classgen/ExtendedVerifier.java b/src/main/org/codehaus/groovy/classgen/ExtendedVerifier.java
index 57cfbfa..f66a95a 100644
--- a/src/main/org/codehaus/groovy/classgen/ExtendedVerifier.java
+++ b/src/main/org/codehaus/groovy/classgen/ExtendedVerifier.java
@@ -22,6 +22,7 @@ import org.codehaus.groovy.ast.*;
 import org.codehaus.groovy.ast.expr.DeclarationExpression;
 import org.codehaus.groovy.ast.stmt.ReturnStatement;
 import org.codehaus.groovy.ast.stmt.Statement;
+import org.codehaus.groovy.ast.tools.ParameterUtils;
 import org.codehaus.groovy.control.AnnotationConstantsVisitor;
 import org.codehaus.groovy.control.CompilerConfiguration;
 import org.codehaus.groovy.control.ErrorCollector;
@@ -46,8 +47,6 @@ import static org.codehaus.groovy.ast.tools.GenericsUtils.createGenericsSpec;
  * <p>
  * Current limitations:
  * - annotations on local variables are not supported
- *
- * @author <a href='mailto:the[dot]mindstorm[at]gmail[dot]com'>Alex Popescu</a>
  */
 public class ExtendedVerifier extends ClassCodeVisitorSupport {
     public static final String JVM_ERROR_MESSAGE = "Please make sure you are running on a JVM >= 1.5";
@@ -234,27 +233,13 @@ public class ExtendedVerifier extends ClassCodeVisitorSupport {
     private static MethodNode getDeclaredMethodCorrected(Map genericsSpec, MethodNode mn, ClassNode correctedNext) {
         for (MethodNode orig :  correctedNext.getDeclaredMethods(mn.getName())) {
             MethodNode method = correctToGenericsSpec(genericsSpec, orig);
-            if (parametersEqual(method.getParameters(), mn.getParameters())) {
+            if (ParameterUtils.parametersEqual(method.getParameters(), mn.getParameters())) {
                 return method;
             }
         }
         return null;
     }
 
-    private static boolean parametersEqual(Parameter[] a, Parameter[] b) {
-        if (a.length == b.length) {
-            boolean answer = true;
-            for (int i = 0; i < a.length; i++) {
-                if (!a[i].getType().equals(b[i].getType())) {
-                    answer = false;
-                    break;
-                }
-            }
-            return answer;
-        }
-        return false;
-    }
-
     /**
      * Resolve metadata and details of the annotation.
      *

http://git-wip-us.apache.org/repos/asf/groovy/blob/3d60dbd7/src/main/org/codehaus/groovy/classgen/asm/OptimizingStatementWriter.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/classgen/asm/OptimizingStatementWriter.java b/src/main/org/codehaus/groovy/classgen/asm/OptimizingStatementWriter.java
index 104eb1f..9e660fa 100644
--- a/src/main/org/codehaus/groovy/classgen/asm/OptimizingStatementWriter.java
+++ b/src/main/org/codehaus/groovy/classgen/asm/OptimizingStatementWriter.java
@@ -25,6 +25,7 @@ import org.codehaus.groovy.ast.*;
 import org.codehaus.groovy.ast.expr.*;
 import org.codehaus.groovy.ast.stmt.*;
 import org.codehaus.groovy.GroovyBugError;
+import org.codehaus.groovy.ast.tools.ParameterUtils;
 import org.codehaus.groovy.classgen.AsmClassGenerator;
 import org.codehaus.groovy.classgen.Verifier;
 import org.codehaus.groovy.control.SourceUnit;
@@ -40,7 +41,6 @@ import static org.codehaus.groovy.ast.tools.WideningCategories.*;
 
 /**
  * A class to write out the optimized statements
- * @author <a href="mailto:blackdrag@gmx.org">Jochen "blackdrag" Theodorou</a>
  */
 public class OptimizingStatementWriter extends StatementWriter {
     
@@ -850,7 +850,7 @@ public class OptimizingStatementWriter extends StatementWriter {
             List<ConstructorNode> cl = node.getDeclaredConstructors();
             MethodNode res = null;
             for (ConstructorNode cn : cl) {
-                if (parametersEqual(cn.getParameters(), paraTypes)) {
+                if (ParameterUtils.parametersEqual(cn.getParameters(), paraTypes)) {
                     res = cn;
                     break;
                 }
@@ -859,20 +859,6 @@ public class OptimizingStatementWriter extends StatementWriter {
             return null;
         }
 
-        private static boolean parametersEqual(Parameter[] a, Parameter[] b) {
-            if (a.length == b.length) {
-                boolean answer = true;
-                for (int i = 0; i < a.length; i++) {
-                    if (!a[i].getType().equals(b[i].getType())) {
-                        answer = false;
-                        break;
-                    }
-                }
-                return answer;
-            }
-            return false;
-        }
-        
         private static boolean validTypeForCall(ClassNode type) {
             // do call only for final classes and primitive types
             if (isPrimitiveType(type)) return true;