GROOVY-8023: changing O(n^2) time complexity of transformMethodCall in 
SuperCallTraitTransformer to O(n)


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

Branch: refs/heads/parrot
Commit: d3dd694969e85050b2b127280ad5ca7dcdfd2180
Parents: e96a961
Author: Jochen Theodorou <blackd...@gmx.org>
Authored: Thu Jan 26 21:01:35 2017 +0100
Committer: Jochen Theodorou <blackd...@gmx.org>
Committed: Thu Jan 26 21:01:35 2017 +0100

----------------------------------------------------------------------
 .../trait/SuperCallTraitTransformer.java        | 40 ++++++++++++++------
 .../codehaus/groovy/transform/trait/Traits.java |  2 +-
 2 files changed, 29 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/d3dd6949/src/main/org/codehaus/groovy/transform/trait/SuperCallTraitTransformer.java
----------------------------------------------------------------------
diff --git 
a/src/main/org/codehaus/groovy/transform/trait/SuperCallTraitTransformer.java 
b/src/main/org/codehaus/groovy/transform/trait/SuperCallTraitTransformer.java
index e403a2c..6ebc5f2 100644
--- 
a/src/main/org/codehaus/groovy/transform/trait/SuperCallTraitTransformer.java
+++ 
b/src/main/org/codehaus/groovy/transform/trait/SuperCallTraitTransformer.java
@@ -19,6 +19,7 @@
 package org.codehaus.groovy.transform.trait;
 
 import groovy.lang.MetaProperty;
+import java.util.List;
 import org.codehaus.groovy.ast.ClassCodeExpressionTransformer;
 import org.codehaus.groovy.ast.ClassNode;
 import org.codehaus.groovy.ast.MethodNode;
@@ -34,8 +35,6 @@ import org.codehaus.groovy.ast.expr.VariableExpression;
 import org.codehaus.groovy.control.SourceUnit;
 import org.codehaus.groovy.syntax.Types;
 
-import java.util.List;
-
 /**
  * This transformer is used to transform calls to 
<code>SomeTrait.super.foo()</code> into the appropriate trait call.
  *
@@ -56,9 +55,6 @@ class SuperCallTraitTransformer extends 
ClassCodeExpressionTransformer {
 
     @Override
     public Expression transform(final Expression exp) {
-        if (exp instanceof PropertyExpression) {
-            return transformPropertyExpression((PropertyExpression) exp);
-        }
         if (exp instanceof MethodCallExpression) {
             return transformMethodCallExpression((MethodCallExpression)exp);
         }
@@ -74,12 +70,17 @@ class SuperCallTraitTransformer extends 
ClassCodeExpressionTransformer {
             BinaryExpression bin = (BinaryExpression) trn;
             Expression leftExpression = bin.getLeftExpression();
             if (bin.getOperation().getType() == Types.EQUAL && leftExpression 
instanceof PropertyExpression) {
-                ClassNode traitReceiver = ((PropertyExpression) 
leftExpression).getObjectExpression().getNodeMetaData(SuperCallTraitTransformer.class);
+                ClassNode traitReceiver = null;
+                PropertyExpression leftPropertyExpression = 
(PropertyExpression) leftExpression;
+                if 
(isTraitSuperPropertyExpression(leftPropertyExpression.getObjectExpression())) {
+                    PropertyExpression pexp = (PropertyExpression) 
leftPropertyExpression.getObjectExpression();
+                    traitReceiver = pexp.getObjectExpression().getType();
+                }
                 if (traitReceiver!=null) {
                     // A.super.foo = ...
                     TraitHelpersTuple helpers = 
Traits.findHelpers(traitReceiver);
                     ClassNode helper = helpers.getHelper();
-                    String setterName = 
MetaProperty.getSetterName(((PropertyExpression) 
leftExpression).getPropertyAsString());
+                    String setterName = 
MetaProperty.getSetterName(leftPropertyExpression.getPropertyAsString());
                     List<MethodNode> methods = helper.getMethods(setterName);
                     for (MethodNode method : methods) {
                         Parameter[] parameters = method.getParameters();
@@ -106,9 +107,10 @@ class SuperCallTraitTransformer extends 
ClassCodeExpressionTransformer {
     }
 
     private Expression transformMethodCallExpression(final 
MethodCallExpression exp) {
-        Expression objectExpression = transform(exp.getObjectExpression());
-        ClassNode traitReceiver = 
objectExpression.getNodeMetaData(SuperCallTraitTransformer.class);
-        if (traitReceiver!=null) {
+        if (isTraitSuperPropertyExpression(exp.getObjectExpression())) {
+            Expression objectExpression = exp.getObjectExpression();
+            ClassNode traitReceiver = ((PropertyExpression) 
objectExpression).getObjectExpression().getType();
+
             TraitHelpersTuple helpers = Traits.findHelpers(traitReceiver);
             // (SomeTrait.super).foo() --> SomeTrait$Helper.foo(this)
             ClassExpression receiver = new ClassExpression(
@@ -123,11 +125,11 @@ class SuperCallTraitTransformer extends 
ClassCodeExpressionTransformer {
                     newArgs.addExpression(transform(expression));
                 }
             } else {
-                newArgs.addExpression(arguments);
+                newArgs.addExpression(transform(arguments));
             }
             MethodCallExpression result = new MethodCallExpression(
                     receiver,
-                    exp.getMethod(),
+                    transform(exp.getMethod()),
                     newArgs
             );
             result.setImplicitThis(false);
@@ -150,4 +152,18 @@ class SuperCallTraitTransformer extends 
ClassCodeExpressionTransformer {
         }
         return super.transform(expression);
     }
+
+    private boolean isTraitSuperPropertyExpression(Expression exp) {
+        if (exp instanceof PropertyExpression) {
+            PropertyExpression pexp = (PropertyExpression) exp;
+            Expression objectExpression = pexp.getObjectExpression();
+            if (objectExpression instanceof ClassExpression) {
+                ClassNode type = objectExpression.getType();
+                if (Traits.isTrait(type) && 
"super".equals(pexp.getPropertyAsString())) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
 }

http://git-wip-us.apache.org/repos/asf/groovy/blob/d3dd6949/src/main/org/codehaus/groovy/transform/trait/Traits.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/transform/trait/Traits.java 
b/src/main/org/codehaus/groovy/transform/trait/Traits.java
index 4a0ac91..b1c9537 100644
--- a/src/main/org/codehaus/groovy/transform/trait/Traits.java
+++ b/src/main/org/codehaus/groovy/transform/trait/Traits.java
@@ -136,7 +136,7 @@ public abstract class Traits {
             try {
                 final ClassLoader classLoader = 
trait.getTypeClass().getClassLoader();
                 String helperClassName = Traits.helperClassName(trait);
-                helperClassNode = 
ClassHelper.make(classLoader.loadClass(helperClassName));
+                helperClassNode = 
ClassHelper.make(Class.forName(helperClassName, false, classLoader));
                 try {
                     fieldHelperClassNode = 
ClassHelper.make(classLoader.loadClass(Traits.fieldHelperClassName(trait)));
                 } catch (ClassNotFoundException e) {

Reply via email to