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/09 01:22:31 UTC

[groovy] branch GROOVY_3_0_X updated: GROOVY-9601: reduce method calls in findClassMember and getPropertyName

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


The following commit(s) were added to refs/heads/GROOVY_3_0_X by this push:
     new b605f35  GROOVY-9601: reduce method calls in findClassMember and getPropertyName
b605f35 is described below

commit b605f35e3bc0a3466a253b884bc801ff63a9aab9
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Wed Jul 8 17:41:08 2020 -0500

    GROOVY-9601: reduce method calls in findClassMember and getPropertyName
    
    (cherry picked from commit 1845e426ce64c404b8cdee9ade93251366a71ef4)
---
 .../apache/groovy/ast/tools/MethodNodeUtils.java   | 50 ++++++++---------
 .../groovy/classgen/VariableScopeVisitor.java      | 62 +++++++++-------------
 2 files changed, 49 insertions(+), 63 deletions(-)

diff --git a/src/main/java/org/apache/groovy/ast/tools/MethodNodeUtils.java b/src/main/java/org/apache/groovy/ast/tools/MethodNodeUtils.java
index 1e2b9d8..7bb057cb 100644
--- a/src/main/java/org/apache/groovy/ast/tools/MethodNodeUtils.java
+++ b/src/main/java/org/apache/groovy/ast/tools/MethodNodeUtils.java
@@ -30,6 +30,10 @@ import static org.apache.groovy.util.BeanUtils.decapitalize;
  * Utility class for working with MethodNodes
  */
 public class MethodNodeUtils {
+
+    private MethodNodeUtils() {
+    }
+
     /**
      * Return the method node's descriptor including its
      * name and parameter types without generics.
@@ -37,7 +41,7 @@ public class MethodNodeUtils {
      * @param mNode the method node
      * @return the method node's abbreviated descriptor excluding the return type
      */
-    public static String methodDescriptorWithoutReturnType(MethodNode mNode) {
+    public static String methodDescriptorWithoutReturnType(final MethodNode mNode) {
         StringBuilder sb = new StringBuilder();
         sb.append(mNode.getName()).append(':');
         for (Parameter p : mNode.getParameters()) {
@@ -53,7 +57,7 @@ public class MethodNodeUtils {
      * @param mNode the method node
      * @return the method node's descriptor
      */
-    public static String methodDescriptor(MethodNode mNode) {
+    public static String methodDescriptor(final MethodNode mNode) {
         StringBuilder sb = new StringBuilder(mNode.getName().length() + mNode.getParameters().length * 10);
         sb.append(mNode.getReturnType().getName());
         sb.append(' ');
@@ -76,35 +80,31 @@ public class MethodNodeUtils {
      * @param mNode a MethodNode
      * @return the property name without the get/set/is prefix if a property or null
      */
-    public static String getPropertyName(MethodNode mNode) {
-        boolean startsWithGet = false;
-        boolean startsWithSet = false;
-        boolean startsWithIs = false;
-        String name = mNode.getName();
-
-        if ((startsWithGet = name.startsWith("get"))
-                || (startsWithSet = name.startsWith("set"))
-                || (startsWithIs = name.startsWith("is"))) {
-
-            final String tmpPname = name.substring(startsWithIs ? 2 : 3);
-            if (!tmpPname.isEmpty()) {
-                if (startsWithSet) {
-                    if (mNode.getParameters().length == 1) {
-                        return decapitalize(tmpPname);
+    public static String getPropertyName(final MethodNode mNode) {
+        final String name = mNode.getName();
+        final int nameLength = name.length();
+        if (nameLength > 2) {
+            switch (name.charAt(0)) {
+                case 'g':
+                    if (nameLength > 3 && name.charAt(1) == 'e' && name.charAt(2) == 't' && mNode.getParameters().length == 0 && !ClassHelper.VOID_TYPE.equals(mNode.getReturnType())) {
+                        return decapitalize(name.substring(3));
+                    }
+                    break;
+                case 's':
+                    if (nameLength > 3 && name.charAt(1) == 'e' && name.charAt(2) == 't' && mNode.getParameters().length == 1 /*&& ClassHelper.VOID_TYPE.equals(mNode.getReturnType())*/) {
+                        return decapitalize(name.substring(3));
                     }
-                } else if (mNode.getParameters().length == 0 && !ClassHelper.VOID_TYPE.equals(mNode.getReturnType())) {
-                    if (startsWithGet || ClassHelper.boolean_TYPE.equals(mNode.getReturnType())) {
-                        return decapitalize(tmpPname);
+                    break;
+                case 'i':
+                    if (name.charAt(1) == 's' && mNode.getParameters().length == 0 && (ClassHelper.boolean_TYPE.equals(mNode.getReturnType()) /*|| ClassHelper.Boolean_TYPE.equals(mNode.getReturnType())*/)) {
+                        return decapitalize(name.substring(2));
                     }
-                }
+                    break;
             }
         }
-
         return null;
     }
 
-    private MethodNodeUtils() { }
-
     /**
      * Gets the code for a method (or constructor) as a block.
      * If no code is found, an empty block will be returned.
@@ -115,7 +115,7 @@ public class MethodNodeUtils {
      * @param node the method (or constructor) node
      * @return the found or created block statement
      */
-    public static BlockStatement getCodeAsBlock(MethodNode node) {
+    public static BlockStatement getCodeAsBlock(final MethodNode node) {
         Statement code = node.getCode();
         BlockStatement block;
         if (code == null) {
diff --git a/src/main/java/org/codehaus/groovy/classgen/VariableScopeVisitor.java b/src/main/java/org/codehaus/groovy/classgen/VariableScopeVisitor.java
index 752267f..b558b21 100644
--- a/src/main/java/org/codehaus/groovy/classgen/VariableScopeVisitor.java
+++ b/src/main/java/org/codehaus/groovy/classgen/VariableScopeVisitor.java
@@ -166,50 +166,36 @@ public class VariableScopeVisitor extends ClassCodeVisitorSupport {
         currentScope.putDeclaredVariable(variable);
     }
 
-    private Variable findClassMember(final ClassNode cn, final String name) {
-        for (ClassNode classNode = cn; null != classNode; classNode = classNode.getSuperClass()) {
-            Variable variable = doFindClassMember(classNode, name);
-            if (null != variable) {
-                return variable;
+    private Variable findClassMember(final ClassNode node, final String name) {
+        for (ClassNode cn = node; cn != null; cn = cn.getSuperClass()) {
+            if (cn.isScript()) {
+                return new DynamicVariable(name, false);
             }
-        }
-
-        return null;
-    }
 
-    private Variable doFindClassMember(final ClassNode cn, final String name) {
-        if (cn == null) return null;
-
-        if (cn.isScript()) {
-            return new DynamicVariable(name, false);
-        }
-
-        for (FieldNode fn : cn.getFields()) {
-            if (name.equals(fn.getName())) return fn;
-        }
-
-        for (MethodNode mn : cn.getMethods()) {
-            if (mn.isAbstract()) {
-                continue;
+            for (FieldNode fn : cn.getFields()) {
+                if (name.equals(fn.getName())) return fn;
             }
-            if (name.equals(getPropertyName(mn))) {
-                PropertyNode property = new PropertyNode(name, mn.getModifiers(), ClassHelper.OBJECT_TYPE, cn, null, null, null);
-                final FieldNode field = property.getField();
-                field.setHasNoRealSourcePosition(true);
-                field.setSynthetic(true);
-                field.setDeclaringClass(cn);
-                property.setDeclaringClass(cn);
-                return property;
+
+            for (PropertyNode pn : cn.getProperties()) {
+                if (name.equals(pn.getName())) return pn;
             }
-        }
 
-        for (PropertyNode pn : cn.getProperties()) {
-            if (pn.getName().equals(name)) return pn;
-        }
+            for (MethodNode mn : cn.getMethods()) {
+                if (!mn.isAbstract() && name.equals(getPropertyName(mn))) {
+                    PropertyNode property = new PropertyNode(name, mn.getModifiers(), ClassHelper.OBJECT_TYPE, cn, null, null, null);
+                    final FieldNode field = property.getField();
+                    field.setHasNoRealSourcePosition(true);
+                    field.setSynthetic(true);
+                    field.setDeclaringClass(cn);
+                    property.setDeclaringClass(cn);
+                    return property;
+                }
+            }
 
-        for (ClassNode face : cn.getInterfaces()) {
-            FieldNode fn = face.getDeclaredField(name);
-            if (fn != null) return fn;
+            for (ClassNode face : cn.getInterfaces()) {
+                FieldNode fn = face.getDeclaredField(name);
+                if (fn != null) return fn;
+            }
         }
 
         return null;