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 2017/05/17 01:34:20 UTC

groovy git commit: GROOVY-7840: Verifier#makeDescriptorWithoutReturnType uses ClassNode#toString with generics (closes #533)

Repository: groovy
Updated Branches:
  refs/heads/master d5fc12260 -> 5ac20ba56


GROOVY-7840: Verifier#makeDescriptorWithoutReturnType uses ClassNode#toString with generics (closes #533)


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

Branch: refs/heads/master
Commit: 5ac20ba56fbb7f71d23218934cb9b39f15ce8858
Parents: d5fc122
Author: paulk <pa...@asert.com.au>
Authored: Wed May 3 19:12:31 2017 +1000
Committer: paulk <pa...@asert.com.au>
Committed: Wed May 17 11:31:58 2017 +1000

----------------------------------------------------------------------
 .../apache/groovy/ast/tools/ClassNodeUtils.java | 53 +++++++++++++++
 .../groovy/ast/tools/MethodNodeUtils.java       | 70 ++++++++++++++++++++
 .../org/codehaus/groovy/ast/MethodNode.java     | 42 ++----------
 .../codehaus/groovy/ast/tools/GeneralUtils.java |  4 ++
 .../org/codehaus/groovy/classgen/Verifier.java  |  6 +-
 .../transform/AbstractASTTransformation.java    | 13 ++--
 .../AutoImplementASTTransformation.java         |  8 +--
 7 files changed, 145 insertions(+), 51 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/5ac20ba5/src/main/org/apache/groovy/ast/tools/ClassNodeUtils.java
----------------------------------------------------------------------
diff --git a/src/main/org/apache/groovy/ast/tools/ClassNodeUtils.java b/src/main/org/apache/groovy/ast/tools/ClassNodeUtils.java
new file mode 100644
index 0000000..b8fd27a
--- /dev/null
+++ b/src/main/org/apache/groovy/ast/tools/ClassNodeUtils.java
@@ -0,0 +1,53 @@
+/*
+ *  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.apache.groovy.ast.tools;
+
+import org.codehaus.groovy.ast.ClassNode;
+
+/**
+ * Utility class for working with ClassNodes
+ */
+public class ClassNodeUtils {
+    /**
+     * Formats a type name into a human readable version. For arrays, appends "[]" to the formatted
+     * type name of the component. For unit class nodes, uses the class node name.
+     *
+     * @param cNode the type to format
+     * @return a human readable version of the type name (java.lang.String[] for example)
+     */
+    public static String formatTypeName(ClassNode cNode) {
+        if (cNode.isArray()) {
+            ClassNode it = cNode;
+            int dim = 0;
+            while (it.isArray()) {
+                dim++;
+                it = it.getComponentType();
+            }
+            StringBuilder sb = new StringBuilder(it.getName().length() + 2 * dim);
+            sb.append(it.getName());
+            for (int i = 0; i < dim; i++) {
+                sb.append("[]");
+            }
+            return sb.toString();
+        }
+        return cNode.getName();
+    }
+
+    private ClassNodeUtils() { }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/5ac20ba5/src/main/org/apache/groovy/ast/tools/MethodNodeUtils.java
----------------------------------------------------------------------
diff --git a/src/main/org/apache/groovy/ast/tools/MethodNodeUtils.java b/src/main/org/apache/groovy/ast/tools/MethodNodeUtils.java
new file mode 100644
index 0000000..b43fc31
--- /dev/null
+++ b/src/main/org/apache/groovy/ast/tools/MethodNodeUtils.java
@@ -0,0 +1,70 @@
+/*
+ *  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.apache.groovy.ast.tools;
+
+import org.codehaus.groovy.ast.MethodNode;
+import org.codehaus.groovy.ast.Parameter;
+
+/**
+ * Utility class for working with MethodNodes
+ */
+public class MethodNodeUtils {
+    /**
+     * Return the method node's descriptor including its
+     * name and parameter types without generics.
+     *
+     * @param mNode the method node
+     * @return the method node's abbreviated descriptor excluding the return type
+     */
+    public static String methodDescriptorWithoutReturnType(MethodNode mNode) {
+        StringBuilder sb = new StringBuilder();
+        mNode.getTypeDescriptor();
+        sb.append(mNode.getName()).append(':');
+        for (Parameter p : mNode.getParameters()) {
+            sb.append(ClassNodeUtils.formatTypeName(p.getType())).append(',');
+        }
+        return sb.toString();
+    }
+
+    /**
+     * Return the method node's descriptor which includes its return type,
+     * name and parameter types without generics.
+     *
+     * @param mNode the method node
+     * @return the method node's descriptor
+     */
+    public static String methodDescriptor(MethodNode mNode) {
+        StringBuilder sb = new StringBuilder(mNode.getName().length() + mNode.getParameters().length * 10);
+        sb.append(mNode.getReturnType().getName());
+        sb.append(' ');
+        sb.append(mNode.getName());
+        sb.append('(');
+        for (int i = 0; i < mNode.getParameters().length; i++) {
+            if (i > 0) {
+                sb.append(", ");
+            }
+            Parameter p = mNode.getParameters()[i];
+            sb.append(ClassNodeUtils.formatTypeName(p.getType()));
+        }
+        sb.append(')');
+        return sb.toString();
+    }
+
+    private MethodNodeUtils() { }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/5ac20ba5/src/main/org/codehaus/groovy/ast/MethodNode.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/ast/MethodNode.java b/src/main/org/codehaus/groovy/ast/MethodNode.java
index 1c867c3..7239a86 100644
--- a/src/main/org/codehaus/groovy/ast/MethodNode.java
+++ b/src/main/org/codehaus/groovy/ast/MethodNode.java
@@ -18,6 +18,7 @@
  */
 package org.codehaus.groovy.ast;
 
+import org.apache.groovy.ast.tools.MethodNodeUtils;
 import org.codehaus.groovy.ast.stmt.BlockStatement;
 import org.codehaus.groovy.ast.stmt.Statement;
 import org.objectweb.asm.Opcodes;
@@ -67,53 +68,18 @@ public class MethodNode extends AnnotatedNode implements Opcodes {
 
     /**
      * The type descriptor for a method node is a string containing the name of the method, its return type,
-     * and its parameter types in a canonical form. For simplicity, I'm using the format of a Java declaration
-     * without parameter names.
+     * and its parameter types in a canonical form. For simplicity, we use the format of a Java declaration
+     * without parameter names or generics.
      *
      * @return the type descriptor
      */
     public String getTypeDescriptor() {
         if (typeDescriptor == null) {
-            StringBuilder buf = new StringBuilder(name.length() + parameters.length * 10);
-            buf.append(returnType.getName());
-            buf.append(' ');
-            buf.append(name);
-            buf.append('(');
-            for (int i = 0; i < parameters.length; i++) {
-                if (i > 0) {
-                    buf.append(", ");
-                }
-                Parameter param = parameters[i];
-                buf.append(formatTypeName(param.getType()));
-            }
-            buf.append(')');
-            typeDescriptor = buf.toString();
+            typeDescriptor = MethodNodeUtils.methodDescriptor(this);
         }
         return typeDescriptor;
     }
 
-    /**
-     * Formats a type name in a readable version. For arrays, appends "[]" to the formatted
-     * type name of the component. For unit class nodes, uses the class node name.
-     * @param type the type to format
-     * @return a human readable version of the type name (java.lang.String[] for example)
-     */
-    private static String formatTypeName(ClassNode type) {
-        if (type.isArray()) {
-            ClassNode it = type;
-            int dim = 0;
-            while (it.isArray()) {
-                dim++;
-                it = it.getComponentType();
-            }
-            StringBuilder sb = new StringBuilder(it.getName().length()+2*dim);
-            sb.append(it.getName());
-            for (int i=0;i<dim;i++) { sb.append("[]"); }
-            return sb.toString();
-        }
-        return type.getName();
-    }
-
     private void invalidateCachedData() {
         typeDescriptor = null;
     }

http://git-wip-us.apache.org/repos/asf/groovy/blob/5ac20ba5/src/main/org/codehaus/groovy/ast/tools/GeneralUtils.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/ast/tools/GeneralUtils.java b/src/main/org/codehaus/groovy/ast/tools/GeneralUtils.java
index 413292a..c00a62d 100644
--- a/src/main/org/codehaus/groovy/ast/tools/GeneralUtils.java
+++ b/src/main/org/codehaus/groovy/ast/tools/GeneralUtils.java
@@ -559,6 +559,10 @@ public class GeneralUtils {
         return new BinaryExpression(lhv, LT, rhv);
     }
 
+    /**
+     * @deprecated use MethodNodeUtils#methodDescriptorWithoutReturnType(MethodNode) instead
+     */
+    @Deprecated
     public static String makeDescriptorWithoutReturnType(MethodNode mn) {
         StringBuilder sb = new StringBuilder();
         sb.append(mn.getName()).append(':');

http://git-wip-us.apache.org/repos/asf/groovy/blob/5ac20ba5/src/main/org/codehaus/groovy/classgen/Verifier.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/classgen/Verifier.java b/src/main/org/codehaus/groovy/classgen/Verifier.java
index 9f90dd0..b98e784 100644
--- a/src/main/org/codehaus/groovy/classgen/Verifier.java
+++ b/src/main/org/codehaus/groovy/classgen/Verifier.java
@@ -73,7 +73,7 @@ import static java.lang.reflect.Modifier.isFinal;
 import static java.lang.reflect.Modifier.isPrivate;
 import static java.lang.reflect.Modifier.isPublic;
 import static java.lang.reflect.Modifier.isStatic;
-import static org.codehaus.groovy.ast.tools.GeneralUtils.makeDescriptorWithoutReturnType;
+import static org.apache.groovy.ast.tools.MethodNodeUtils.methodDescriptorWithoutReturnType;
 import static org.codehaus.groovy.ast.tools.GenericsUtils.correctToGenericsSpec;
 import static org.codehaus.groovy.ast.tools.GenericsUtils.createGenericsSpec;
 
@@ -266,7 +266,7 @@ public class Verifier implements GroovyClassVisitor, Opcodes {
         Set<String> descriptors = new HashSet<String>();
         for (MethodNode mn : cn.getMethods()) {
             if (mn.isSynthetic()) continue;
-            String mySig = makeDescriptorWithoutReturnType(mn);
+            String mySig = methodDescriptorWithoutReturnType(mn);
             if (descriptors.contains(mySig)) {
                 if (mn.isScriptBody() || mySig.equals(scriptBodySignatureWithoutReturnType(cn))) {
                     throw new RuntimeParserException("The method " + mn.getText() +
@@ -282,7 +282,7 @@ public class Verifier implements GroovyClassVisitor, Opcodes {
 
     private static String scriptBodySignatureWithoutReturnType(ClassNode cn) {
         for (MethodNode mn : cn.getMethods()) {
-            if (mn.isScriptBody()) return makeDescriptorWithoutReturnType(mn);
+            if (mn.isScriptBody()) return methodDescriptorWithoutReturnType(mn);
         }
         return null;
     }

http://git-wip-us.apache.org/repos/asf/groovy/blob/5ac20ba5/src/main/org/codehaus/groovy/transform/AbstractASTTransformation.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/transform/AbstractASTTransformation.java b/src/main/org/codehaus/groovy/transform/AbstractASTTransformation.java
index 7a289ea..24313f6 100644
--- a/src/main/org/codehaus/groovy/transform/AbstractASTTransformation.java
+++ b/src/main/org/codehaus/groovy/transform/AbstractASTTransformation.java
@@ -18,6 +18,7 @@
  */
 package org.codehaus.groovy.transform;
 
+import org.apache.groovy.ast.tools.MethodNodeUtils;
 import org.codehaus.groovy.GroovyBugError;
 import org.codehaus.groovy.ast.ASTNode;
 import org.codehaus.groovy.ast.AnnotatedNode;
@@ -285,7 +286,7 @@ public abstract class AbstractASTTransformation implements Opcodes, ASTTransform
     @Deprecated
     public static boolean shouldSkipOnDescriptor(boolean checkReturn, Map genericsSpec, MethodNode mNode, List<ClassNode> excludeTypes, List<ClassNode> includeTypes) {
         String descriptor = mNode.getTypeDescriptor();
-        String descriptorNoReturn = GeneralUtils.makeDescriptorWithoutReturnType(mNode);
+        String descriptorNoReturn = MethodNodeUtils.methodDescriptorWithoutReturnType(mNode);
         for (ClassNode cn : excludeTypes) {
             List<ClassNode> remaining = new LinkedList<ClassNode>();
             remaining.add(cn);
@@ -300,7 +301,7 @@ public abstract class AbstractASTTransformation implements Opcodes, ASTTransform
                             String md = correctedMethodNode.getTypeDescriptor();
                             if (md.equals(descriptor)) return true;
                         } else {
-                            String md = GeneralUtils.makeDescriptorWithoutReturnType(correctedMethodNode);
+                            String md = MethodNodeUtils.methodDescriptorWithoutReturnType(correctedMethodNode);
                             if (md.equals(descriptorNoReturn)) return true;
                         }
                     }
@@ -323,7 +324,7 @@ public abstract class AbstractASTTransformation implements Opcodes, ASTTransform
                             String md = correctedMethodNode.getTypeDescriptor();
                             if (md.equals(descriptor)) return false;
                         } else {
-                            String md = GeneralUtils.makeDescriptorWithoutReturnType(correctedMethodNode);
+                            String md = MethodNodeUtils.methodDescriptorWithoutReturnType(correctedMethodNode);
                             if (md.equals(descriptorNoReturn)) return false;
                         }
                     }
@@ -336,7 +337,7 @@ public abstract class AbstractASTTransformation implements Opcodes, ASTTransform
     public static boolean shouldSkipOnDescriptorUndefinedAware(boolean checkReturn, Map genericsSpec, MethodNode mNode,
                                                   List<ClassNode> excludeTypes, List<ClassNode> includeTypes) {
         String descriptor = mNode.getTypeDescriptor();
-        String descriptorNoReturn = GeneralUtils.makeDescriptorWithoutReturnType(mNode);
+        String descriptorNoReturn = MethodNodeUtils.methodDescriptorWithoutReturnType(mNode);
         if (excludeTypes != null) {
             for (ClassNode cn : excludeTypes) {
                 List<ClassNode> remaining = new LinkedList<ClassNode>();
@@ -352,7 +353,7 @@ public abstract class AbstractASTTransformation implements Opcodes, ASTTransform
                                 String md = correctedMethodNode.getTypeDescriptor();
                                 if (md.equals(descriptor)) return true;
                             } else {
-                                String md = GeneralUtils.makeDescriptorWithoutReturnType(correctedMethodNode);
+                                String md = MethodNodeUtils.methodDescriptorWithoutReturnType(correctedMethodNode);
                                 if (md.equals(descriptorNoReturn)) return true;
                             }
                         }
@@ -376,7 +377,7 @@ public abstract class AbstractASTTransformation implements Opcodes, ASTTransform
                             String md = correctedMethodNode.getTypeDescriptor();
                             if (md.equals(descriptor)) return false;
                         } else {
-                            String md = GeneralUtils.makeDescriptorWithoutReturnType(correctedMethodNode);
+                            String md = MethodNodeUtils.methodDescriptorWithoutReturnType(correctedMethodNode);
                             if (md.equals(descriptorNoReturn)) return false;
                         }
                     }

http://git-wip-us.apache.org/repos/asf/groovy/blob/5ac20ba5/src/main/org/codehaus/groovy/transform/AutoImplementASTTransformation.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/transform/AutoImplementASTTransformation.java b/src/main/org/codehaus/groovy/transform/AutoImplementASTTransformation.java
index 5ec874f..74124fd 100644
--- a/src/main/org/codehaus/groovy/transform/AutoImplementASTTransformation.java
+++ b/src/main/org/codehaus/groovy/transform/AutoImplementASTTransformation.java
@@ -48,7 +48,7 @@ import static org.codehaus.groovy.ast.ClassHelper.make;
 import static org.codehaus.groovy.ast.expr.ArgumentListExpression.EMPTY_ARGUMENTS;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.constX;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.ctorX;
-import static org.codehaus.groovy.ast.tools.GeneralUtils.makeDescriptorWithoutReturnType;
+import static org.apache.groovy.ast.tools.MethodNodeUtils.methodDescriptorWithoutReturnType;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.returnS;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.throwS;
 import static org.codehaus.groovy.ast.tools.GenericsUtils.correctToGenericsSpec;
@@ -107,7 +107,7 @@ public class AutoImplementASTTransformation extends AbstractASTTransformation {
     private static Map<String, MethodNode> getAllCorrectedMethodsMap(ClassNode cNode) {
         Map<String, MethodNode> result = new HashMap<String, MethodNode>();
         for (MethodNode mn : cNode.getMethods()) {
-            result.put(makeDescriptorWithoutReturnType(mn), mn);
+            result.put(methodDescriptorWithoutReturnType(mn), mn);
         }
         ClassNode next = cNode;
         while (true) {
@@ -118,7 +118,7 @@ public class AutoImplementASTTransformation extends AbstractASTTransformation {
                     ClassNode correctedClass = correctToGenericsSpecRecurse(genericsSpec, next);
                     MethodNode found = getDeclaredMethodCorrected(genericsSpec, correctedMethod, correctedClass);
                     if (found != null) {
-                        String td = makeDescriptorWithoutReturnType(found);
+                        String td = methodDescriptorWithoutReturnType(found);
                         if (result.containsKey(td) && !result.get(td).isAbstract()) {
                             continue;
                         }
@@ -137,7 +137,7 @@ public class AutoImplementASTTransformation extends AbstractASTTransformation {
                         MethodNode correctedMethod = correctToGenericsSpec(genericsSpec, nextMethod);
                         MethodNode found = getDeclaredMethodCorrected(updatedGenericsSpec, correctedMethod, correctedInterface);
                         if (found != null) {
-                            String td = makeDescriptorWithoutReturnType(found);
+                            String td = methodDescriptorWithoutReturnType(found);
                             if (result.containsKey(td) && !result.get(td).isAbstract()) {
                                 continue;
                             }