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:35:45 UTC
[2/2] groovy git commit: GROOVY-7840:
Verifier#makeDescriptorWithoutReturnType uses ClassNode#toString with
generics (closes #533)
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/771b838a
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/771b838a
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/771b838a
Branch: refs/heads/GROOVY_2_5_X
Commit: 771b838aa3de2764d7666c502a2d7dc9c518c4b5
Parents: e7a860c
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:35:27 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/771b838a/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/771b838a/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/771b838a/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/771b838a/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/771b838a/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/771b838a/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/771b838a/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;
}