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 2021/11/27 14:17:44 UTC

[groovy] branch master updated: Minor refactoring: simplify code of tail recursive transformation

This is an automated email from the ASF dual-hosted git repository.

sunlan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git


The following commit(s) were added to refs/heads/master by this push:
     new 6993045  Minor refactoring: simplify code of tail recursive transformation
6993045 is described below

commit 6993045f820f8854438208e732b734e5238438dd
Author: Daniel Sun <su...@apache.org>
AuthorDate: Sat Nov 27 20:59:40 2021 +0800

    Minor refactoring: simplify code of tail recursive transformation
---
 .../transform/tailrec/InWhileLoopWrapper.java      | 17 +++--
 .../transform/tailrec/RecursivenessTester.java     |  6 +-
 .../ReturnStatementToIterationConverter.java       | 69 ++++++++---------
 .../transform/tailrec/StatementReplacer.java       | 58 ++++----------
 .../tailrec/TailRecursiveASTTransformation.java    | 89 +++++++++-------------
 .../tailrec/TernaryToIfStatementConverter.java     |  3 +-
 .../tailrec/VariableExpressionReplacer.java        |  3 +-
 7 files changed, 98 insertions(+), 147 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/transform/tailrec/InWhileLoopWrapper.java b/src/main/java/org/codehaus/groovy/transform/tailrec/InWhileLoopWrapper.java
index baed933..69a7c07 100644
--- a/src/main/java/org/codehaus/groovy/transform/tailrec/InWhileLoopWrapper.java
+++ b/src/main/java/org/codehaus/groovy/transform/tailrec/InWhileLoopWrapper.java
@@ -27,11 +27,16 @@ import org.codehaus.groovy.ast.stmt.EmptyStatement;
 import org.codehaus.groovy.ast.stmt.Statement;
 import org.codehaus.groovy.ast.stmt.TryCatchStatement;
 import org.codehaus.groovy.ast.stmt.WhileStatement;
-import org.codehaus.groovy.ast.tools.GeneralUtils;
-import org.codehaus.groovy.runtime.DefaultGroovyMethods;
 
 import java.util.List;
 
+import static org.codehaus.groovy.ast.tools.GeneralUtils.block;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.boolX;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.catchS;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.constX;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.param;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.tryCatchS;
+
 /**
  * Wrap the body of a method in a while loop, nested in a try-catch.
  * This is the first step in making a tail recursive method iterative.
@@ -44,13 +49,13 @@ import java.util.List;
  */
 public class InWhileLoopWrapper {
     public void wrap(MethodNode method) {
-        BlockStatement oldBody = DefaultGroovyMethods.asType(method.getCode(), BlockStatement.class);
-        TryCatchStatement tryCatchStatement = GeneralUtils.tryCatchS(oldBody, EmptyStatement.INSTANCE, GeneralUtils.catchS(GeneralUtils.param(ClassHelper.make(GotoRecurHereException.class), "ignore"), new ContinueStatement(InWhileLoopWrapper.LOOP_LABEL)));
+        BlockStatement oldBody = (BlockStatement) method.getCode();
+        TryCatchStatement tryCatchStatement = tryCatchS(oldBody, EmptyStatement.INSTANCE, catchS(param(ClassHelper.make(GotoRecurHereException.class), "ignore"), new ContinueStatement(InWhileLoopWrapper.LOOP_LABEL)));
 
-        WhileStatement whileLoop = new WhileStatement(GeneralUtils.boolX(GeneralUtils.constX(true)), GeneralUtils.block(new VariableScope(method.getVariableScope()), tryCatchStatement));
+        WhileStatement whileLoop = new WhileStatement(boolX(constX(true)), block(new VariableScope(method.getVariableScope()), tryCatchStatement));
         List<Statement> whileLoopStatements = ((BlockStatement) whileLoop.getLoopBlock()).getStatements();
         if (whileLoopStatements.size() > 0) whileLoopStatements.get(0).setStatementLabel(LOOP_LABEL);
-        BlockStatement newBody = GeneralUtils.block(new VariableScope(method.getVariableScope()));
+        BlockStatement newBody = block(new VariableScope(method.getVariableScope()));
         newBody.addStatement(whileLoop);
         method.setCode(newBody);
     }
diff --git a/src/main/java/org/codehaus/groovy/transform/tailrec/RecursivenessTester.java b/src/main/java/org/codehaus/groovy/transform/tailrec/RecursivenessTester.java
index 592b50c..13f094a 100644
--- a/src/main/java/org/codehaus/groovy/transform/tailrec/RecursivenessTester.java
+++ b/src/main/java/org/codehaus/groovy/transform/tailrec/RecursivenessTester.java
@@ -29,13 +29,13 @@ import org.codehaus.groovy.ast.expr.MethodCallExpression;
 import org.codehaus.groovy.ast.expr.StaticMethodCallExpression;
 import org.codehaus.groovy.ast.expr.TupleExpression;
 import org.codehaus.groovy.ast.expr.VariableExpression;
-import org.codehaus.groovy.runtime.DefaultGroovyMethods;
 
 import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;
 
+import static org.codehaus.groovy.runtime.DefaultGroovyMethods.invokeMethod;
 import static org.codehaus.groovy.runtime.DefaultGroovyMethods.transpose;
 
 /**
@@ -87,7 +87,7 @@ public class RecursivenessTester {
             return false;
         }
 
-        return ((boolean) (DefaultGroovyMethods.invokeMethod(call.getObjectExpression(), "isThisExpression", new Object[0])));
+        return ((boolean) (invokeMethod(call.getObjectExpression(), "isThisExpression", EMPTY_OBJECT_ARRAY)));
     }
 
     private boolean methodParamsMatchCallArgs(MethodNode method, Expression call) {
@@ -118,4 +118,6 @@ public class RecursivenessTester {
         ClassNode boxedParam = ClassHelper.getWrapper(paramType);
         return boxedArg.isDerivedFrom(boxedParam) || boxedParam.isDerivedFrom(boxedArg);
     }
+
+    private static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
 }
diff --git a/src/main/java/org/codehaus/groovy/transform/tailrec/ReturnStatementToIterationConverter.java b/src/main/java/org/codehaus/groovy/transform/tailrec/ReturnStatementToIterationConverter.java
index 7f4beaf..e1c37bc 100644
--- a/src/main/java/org/codehaus/groovy/transform/tailrec/ReturnStatementToIterationConverter.java
+++ b/src/main/java/org/codehaus/groovy/transform/tailrec/ReturnStatementToIterationConverter.java
@@ -18,7 +18,6 @@
  */
 package org.codehaus.groovy.transform.tailrec;
 
-import groovy.lang.Closure;
 import org.codehaus.groovy.ast.ClassNode;
 import org.codehaus.groovy.ast.expr.BinaryExpression;
 import org.codehaus.groovy.ast.expr.Expression;
@@ -29,14 +28,17 @@ import org.codehaus.groovy.ast.stmt.BlockStatement;
 import org.codehaus.groovy.ast.stmt.ExpressionStatement;
 import org.codehaus.groovy.ast.stmt.ReturnStatement;
 import org.codehaus.groovy.ast.stmt.Statement;
-import org.codehaus.groovy.ast.tools.GeneralUtils;
-import org.codehaus.groovy.runtime.DefaultGroovyMethods;
 
 import java.util.ArrayList;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.stream.Collectors;
+
+import static org.codehaus.groovy.ast.tools.GeneralUtils.assignS;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.varX;
+import static org.codehaus.groovy.runtime.DefaultGroovyMethods.minus;
 
 /**
  * Translates all return statements into an invocation of the next iteration. This can be either
@@ -57,13 +59,13 @@ public class ReturnStatementToIterationConverter {
         this.recurStatement = recurStatement;
     }
 
-    public Statement convert(ReturnStatement statement, final Map<Integer, Map> positionMapping) {
+    public Statement convert(ReturnStatement statement, final Map<Integer, Map<String, Object>> positionMapping) {
         Expression recursiveCall = statement.getExpression();
         if (!isAMethodCalls(recursiveCall)) return statement;
 
-        final Map<String, Map> tempMapping = new LinkedHashMap<String, Map>();
+        final Map<String, Map<String, Object>> tempMapping = new LinkedHashMap<>();
         final Map<String, ExpressionStatement> tempDeclarations = new LinkedHashMap<>();
-        final List<ExpressionStatement> argAssignments = new ArrayList<ExpressionStatement>();
+        final List<ExpressionStatement> argAssignments = new ArrayList<>();
 
         final BlockStatement result = new BlockStatement();
         result.copyStatementLabels(statement);
@@ -71,25 +73,20 @@ public class ReturnStatementToIterationConverter {
         /* Create temp declarations for all method arguments.
          * Add the declarations and var mapping to tempMapping and tempDeclarations for further reference.
          */
-        DefaultGroovyMethods.eachWithIndex(getArguments(recursiveCall), new Closure<Void>(this, this) {
-            public void doCall(Expression expression, int index) {
-                ExpressionStatement tempDeclaration = createTempDeclaration(index, positionMapping, tempMapping, tempDeclarations);
-                result.addStatement(tempDeclaration);
-            }
-
-        });
+        final List<Expression> arguments = getArguments(recursiveCall);
+        for (int i = 0, n = arguments.size(); i < n; i++) {
+            ExpressionStatement tempDeclaration = createTempDeclaration(i, positionMapping, tempMapping, tempDeclarations);
+            result.addStatement(tempDeclaration);
+        }
 
         /*
          * Assign the iteration variables their new value before recuring
          */
-        DefaultGroovyMethods.eachWithIndex(getArguments(recursiveCall), new Closure<Void>(this, this) {
-            public void doCall(Expression expression, int index) {
-                ExpressionStatement argAssignment = createAssignmentToIterationVariable(expression, index, positionMapping);
-                argAssignments.add(argAssignment);
-                result.addStatement(argAssignment);
-            }
-
-        });
+        for (int i = 0, n = arguments.size(); i < n; i++) {
+            ExpressionStatement argAssignment = createAssignmentToIterationVariable(arguments.get(i), i, positionMapping);
+            argAssignments.add(argAssignment);
+            result.addStatement(argAssignment);
+        }
 
         Set<String> unusedTemps = replaceAllArgUsages(argAssignments, tempMapping);
         for (String temp : unusedTemps) {
@@ -101,19 +98,19 @@ public class ReturnStatementToIterationConverter {
         return result;
     }
 
-    private ExpressionStatement createAssignmentToIterationVariable(Expression expression, int index, Map<Integer, Map> positionMapping) {
+    private ExpressionStatement createAssignmentToIterationVariable(Expression expression, int index, Map<Integer, Map<String, Object>> positionMapping) {
         String argName = (String) positionMapping.get(index).get("name");
-        ClassNode argAndTempType = DefaultGroovyMethods.asType(positionMapping.get(index).get("type"), ClassNode.class);
-        ExpressionStatement argAssignment = (ExpressionStatement) GeneralUtils.assignS(GeneralUtils.varX(argName, argAndTempType), expression);
+        ClassNode argAndTempType = (ClassNode) positionMapping.get(index).get("type");
+        ExpressionStatement argAssignment = (ExpressionStatement) assignS(varX(argName, argAndTempType), expression);
         return argAssignment;
     }
 
-    private ExpressionStatement createTempDeclaration(int index, Map<Integer, Map> positionMapping, Map<String, Map> tempMapping, Map<String, ExpressionStatement> tempDeclarations) {
-        final String argName = (String) positionMapping.get(index).get("name");
+    private ExpressionStatement createTempDeclaration(int index, Map<Integer, Map<String, Object>> positionMapping, Map<String, Map<String, Object>> tempMapping, Map<String, ExpressionStatement> tempDeclarations) {
+        String argName = (String) positionMapping.get(index).get("name");
+        ClassNode argAndTempType = (ClassNode) positionMapping.get(index).get("type");
         String tempName = "_" + argName + "_";
-        ClassNode argAndTempType = DefaultGroovyMethods.asType(positionMapping.get(index).get("type"), ClassNode.class);
         ExpressionStatement tempDeclaration = AstHelper.createVariableAlias(tempName, argAndTempType, argName);
-        Map<String, Object> map = new LinkedHashMap<String, Object>(2);
+        Map<String, Object> map = new LinkedHashMap<>(2);
         map.put("name", tempName);
         map.put("type", argAndTempType);
         tempMapping.put(argName, map);
@@ -135,19 +132,13 @@ public class ReturnStatementToIterationConverter {
         return MethodCallExpression.class == clazz || StaticMethodCallExpression.class == clazz;
     }
 
-    private Set<String> replaceAllArgUsages(List<ExpressionStatement> iterationVariablesAssignmentNodes, Map<String, Map> tempMapping) {
-        Set<String> unusedTempNames = DefaultGroovyMethods.asType(DefaultGroovyMethods.collect(tempMapping.values(), new Closure<String>(this, this) {
-            public String doCall(Map nameAndType) {
-                return (String) nameAndType.get("name");
-            }
-
-        }), Set.class);
-        VariableReplacedListener tracker = new UsedVariableTracker();
+    private Set<String> replaceAllArgUsages(List<ExpressionStatement> iterationVariablesAssignmentNodes, Map<String, Map<String, Object>> tempMapping) {
+        Set<String> unusedTempNames = tempMapping.values().stream().map(nameAndType -> (String) nameAndType.get("name")).collect(Collectors.toSet());
+        UsedVariableTracker tracker = new UsedVariableTracker();
         for (ExpressionStatement statement : iterationVariablesAssignmentNodes) {
-            replaceArgUsageByTempUsage((BinaryExpression) statement.getExpression(), tempMapping, (UsedVariableTracker) tracker);
+            replaceArgUsageByTempUsage((BinaryExpression) statement.getExpression(), tempMapping, tracker);
         }
-
-        unusedTempNames = DefaultGroovyMethods.minus(unusedTempNames, ((UsedVariableTracker) tracker).getUsedVariableNames());
+        unusedTempNames = minus(unusedTempNames, tracker.getUsedVariableNames());
         return unusedTempNames;
     }
 
diff --git a/src/main/java/org/codehaus/groovy/transform/tailrec/StatementReplacer.java b/src/main/java/org/codehaus/groovy/transform/tailrec/StatementReplacer.java
index d404006..32831ea 100644
--- a/src/main/java/org/codehaus/groovy/transform/tailrec/StatementReplacer.java
+++ b/src/main/java/org/codehaus/groovy/transform/tailrec/StatementReplacer.java
@@ -28,10 +28,10 @@ import org.codehaus.groovy.ast.stmt.ForStatement;
 import org.codehaus.groovy.ast.stmt.IfStatement;
 import org.codehaus.groovy.ast.stmt.Statement;
 import org.codehaus.groovy.ast.stmt.WhileStatement;
-import org.codehaus.groovy.runtime.DefaultGroovyMethods;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.function.Consumer;
 
 /**
  * Tool for replacing Statement objects in an AST by other Statement instances.
@@ -58,72 +58,42 @@ public class StatementReplacer extends CodeVisitorSupport {
     }
 
     public void visitBlockStatement(final BlockStatement block) {
-        List<Statement> copyOfStatements = new ArrayList<Statement>(block.getStatements());
-        DefaultGroovyMethods.eachWithIndex(copyOfStatements, new Closure<Void>(this, this) {
-            public void doCall(Statement statement, final int index) {
-                replaceIfNecessary(statement, new Closure<Statement>(StatementReplacer.this, StatementReplacer.this) {
-                    public Statement doCall(Statement node) {
-                        block.getStatements().set(index, node);
-                        return node;
-                    }
-                });
-            }
-        });
+        List<Statement> copyOfStatements = new ArrayList<>(block.getStatements());
+        for (int i = 0, n = copyOfStatements.size(); i < n; i++) {
+            final int index = i;
+            Statement statement = copyOfStatements.get(index);
+            replaceIfNecessary(statement, (Statement node) -> block.getStatements().set(index, node));
+        }
         super.visitBlockStatement(block);
     }
 
     public void visitIfElse(final IfStatement ifElse) {
-        replaceIfNecessary(ifElse.getIfBlock(), new Closure<Statement>(this, this) {
-            public Statement doCall(Statement s) {
-                ifElse.setIfBlock(s);
-                return s;
-            }
-        });
-        replaceIfNecessary(ifElse.getElseBlock(), new Closure<Statement>(this, this) {
-            public Statement doCall(Statement s) {
-                ifElse.setElseBlock(s);
-                return s;
-            }
-        });
+        replaceIfNecessary(ifElse.getIfBlock(), ifElse::setIfBlock);
+        replaceIfNecessary(ifElse.getElseBlock(), ifElse::setElseBlock);
         super.visitIfElse(ifElse);
     }
 
     public void visitForLoop(final ForStatement forLoop) {
-        replaceIfNecessary(forLoop.getLoopBlock(), new Closure<Statement>(this, this) {
-            public Statement doCall(Statement s) {
-                forLoop.setLoopBlock(s);
-                return s;
-            }
-        });
+        replaceIfNecessary(forLoop.getLoopBlock(), forLoop::setLoopBlock);
         super.visitForLoop(forLoop);
     }
 
     public void visitWhileLoop(final WhileStatement loop) {
-        replaceIfNecessary(loop.getLoopBlock(), new Closure<Statement>(this, this) {
-            public Statement doCall(Statement s) {
-                loop.setLoopBlock(s);
-                return s;
-            }
-        });
+        replaceIfNecessary(loop.getLoopBlock(), loop::setLoopBlock);
         super.visitWhileLoop(loop);
     }
 
     public void visitDoWhileLoop(final DoWhileStatement loop) {
-        replaceIfNecessary(loop.getLoopBlock(), new Closure<Statement>(this, this) {
-            public Statement doCall(Statement s) {
-                loop.setLoopBlock(s);
-                return s;
-            }
-        });
+        replaceIfNecessary(loop.getLoopBlock(), loop::setLoopBlock);
         super.visitDoWhileLoop(loop);
     }
 
-    private void replaceIfNecessary(Statement nodeToCheck, Closure replacementCode) {
+    private void replaceIfNecessary(Statement nodeToCheck, Consumer<? super Statement> replacementCode) {
         if (conditionFulfilled(nodeToCheck)) {
             Statement replacement = replaceWith.call(nodeToCheck);
             replacement.setSourcePosition(nodeToCheck);
             replacement.copyNodeMetaData(nodeToCheck);
-            replacementCode.call(replacement);
+            replacementCode.accept(replacement);
         }
     }
 
diff --git a/src/main/java/org/codehaus/groovy/transform/tailrec/TailRecursiveASTTransformation.java b/src/main/java/org/codehaus/groovy/transform/tailrec/TailRecursiveASTTransformation.java
index d406f39..721f7b2 100644
--- a/src/main/java/org/codehaus/groovy/transform/tailrec/TailRecursiveASTTransformation.java
+++ b/src/main/java/org/codehaus/groovy/transform/tailrec/TailRecursiveASTTransformation.java
@@ -39,10 +39,10 @@ import org.codehaus.groovy.classgen.ReturnAdder;
 import org.codehaus.groovy.classgen.VariableScopeVisitor;
 import org.codehaus.groovy.control.CompilePhase;
 import org.codehaus.groovy.control.SourceUnit;
-import org.codehaus.groovy.runtime.DefaultGroovyMethods;
 import org.codehaus.groovy.transform.AbstractASTTransformation;
 import org.codehaus.groovy.transform.GroovyASTTransformation;
 
+import java.util.Arrays;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
@@ -57,16 +57,13 @@ public class TailRecursiveASTTransformation extends AbstractASTTransformation {
     @Override
     public void visit(ASTNode[] nodes, SourceUnit source) {
         init(nodes, source);
-
-        MethodNode method = DefaultGroovyMethods.asType(nodes[1], MethodNode.class);
+        MethodNode method = (MethodNode) nodes[1];
 
         if (method.isAbstract()) {
             addError("Annotation " + TailRecursiveASTTransformation.getMY_TYPE_NAME() + " cannot be used for abstract methods.", method);
             return;
-
         }
 
-
         if (hasAnnotation(method, ClassHelper.make(Memoized.class))) {
             ClassNode memoizedClassNode = ClassHelper.make(Memoized.class);
             for (AnnotationNode annotationNode : method.getAnnotations()) {
@@ -74,22 +71,16 @@ public class TailRecursiveASTTransformation extends AbstractASTTransformation {
                 if (annotationNode.getClassNode().equals(memoizedClassNode)) {
                     addError("Annotation " + TailRecursiveASTTransformation.getMY_TYPE_NAME() + " must be placed before annotation @Memoized.", annotationNode);
                     return;
-
                 }
-
             }
-
         }
 
-
         if (!hasRecursiveMethodCalls(method)) {
             AnnotationNode annotationNode = method.getAnnotations(ClassHelper.make(TailRecursive.class)).get(0);
             addError("No recursive calls detected. You must remove annotation " + TailRecursiveASTTransformation.getMY_TYPE_NAME() + ".", annotationNode);
             return;
-
         }
 
-
         transformToIteration(method, source);
         ensureAllRecursiveCallsHaveBeenTransformed(method);
     }
@@ -105,7 +96,6 @@ public class TailRecursiveASTTransformation extends AbstractASTTransformation {
         } else {
             transformNonVoidMethodToIteration(method, source);
         }
-
     }
 
     private void transformVoidMethodToIteration(MethodNode method) {
@@ -140,13 +130,11 @@ public class TailRecursiveASTTransformation extends AbstractASTTransformation {
 
                 return ((ReturnStatement) node).getExpression() instanceof TernaryExpression;
             }
-
         };
         Closure<Statement> replaceWithIfStatement = new Closure<Statement>(this, this) {
             public Statement doCall(ReturnStatement statement) {
                 return ternaryToIfStatement.convert(statement);
             }
-
         };
         StatementReplacer replacer = new StatementReplacer(whenReturnWithTernary, replaceWithIfStatement);
         replacer.replaceIn(method.getCode());
@@ -154,13 +142,17 @@ public class TailRecursiveASTTransformation extends AbstractASTTransformation {
     }
 
     private void addLocalVariablesForAllParameters(MethodNode method, Map<String, Map> nameAndTypeMapping) {
-        final BlockStatement code = DefaultGroovyMethods.asType(method.getCode(), BlockStatement.class);
-        DefaultGroovyMethods.each(nameAndTypeMapping, new Closure<Void>(this, this) {
-            public void doCall(String paramName, Map localNameAndType) {
-                code.getStatements().add(0, AstHelper.createVariableDefinition((String) localNameAndType.get("name"), (ClassNode) localNameAndType.get("type"), new VariableExpression(paramName, (ClassNode) localNameAndType.get("type"))));
-            }
-
-        });
+        final BlockStatement code = (BlockStatement) method.getCode();
+        nameAndTypeMapping.forEach((paramName, localNameAndType) ->
+                code.getStatements().add(
+                        0,
+                        AstHelper.createVariableDefinition(
+                                (String) localNameAndType.get("name"),
+                                (ClassNode) localNameAndType.get("type"),
+                                new VariableExpression(paramName, (ClassNode) localNameAndType.get("type"))
+                        )
+                )
+        );
     }
 
     private void replaceAllAccessToParams(MethodNode method, Map<String, Map> nameAndTypeMapping) {
@@ -168,36 +160,33 @@ public class TailRecursiveASTTransformation extends AbstractASTTransformation {
     }
 
     public Map<String, Map> name2VariableMappingFor(MethodNode method) {
-        final Map<String, Map> nameAndTypeMapping = new LinkedHashMap<String, Map>();
-        DefaultGroovyMethods.each(method.getParameters(), new Closure<LinkedHashMap<String, Object>>(this, this) {
-            public LinkedHashMap<String, Object> doCall(Parameter param) {
-                String paramName = param.getName();
-                ClassNode paramType = DefaultGroovyMethods.asType(param.getType(), ClassNode.class);
-                String iterationVariableName = iterationVariableName(paramName);
-                LinkedHashMap<String, Object> map = new LinkedHashMap<String, Object>(2);
-                map.put("name", iterationVariableName);
-                map.put("type", paramType);
-                return putAt0(nameAndTypeMapping, paramName, map);
-            }
-
+        final Map<String, Map> nameAndTypeMapping = new LinkedHashMap<>();
+        Arrays.stream(method.getParameters()).forEach((Parameter param) -> {
+            String paramName = param.getName();
+            ClassNode paramType = param.getType();
+            String iterationVariableName = iterationVariableName(paramName);
+            LinkedHashMap<String, Object> map = new LinkedHashMap<>(2);
+            map.put("name", iterationVariableName);
+            map.put("type", paramType);
+            putAt0(nameAndTypeMapping, paramName, map);
         });
+
         return nameAndTypeMapping;
     }
 
     public Map<Integer, Map> position2VariableMappingFor(MethodNode method) {
-        final Map<Integer, Map> positionMapping = new LinkedHashMap<Integer, Map>();
-        DefaultGroovyMethods.eachWithIndex(method.getParameters(), new Closure<LinkedHashMap<String, Object>>(this, this) {
-            public LinkedHashMap<String, Object> doCall(Parameter param, int index) {
-                String paramName = param.getName();
-                ClassNode paramType = DefaultGroovyMethods.asType(param.getType(), ClassNode.class);
-                String iterationVariableName = TailRecursiveASTTransformation.this.iterationVariableName(paramName);
-                LinkedHashMap<String, Object> map = new LinkedHashMap<String, Object>(2);
-                map.put("name", iterationVariableName);
-                map.put("type", paramType);
-                return putAt0(positionMapping, index, map);
-            }
-
-        });
+        final Map<Integer, Map> positionMapping = new LinkedHashMap<>();
+        final Parameter[] parameters = method.getParameters();
+        for (int i = 0, n = parameters.length; i < n; i++) {
+            Parameter param = parameters[i];
+            String paramName = param.getName();
+            ClassNode paramType = param.getType();
+            String iterationVariableName = TailRecursiveASTTransformation.this.iterationVariableName(paramName);
+            LinkedHashMap<String, Object> map = new LinkedHashMap<>(2);
+            map.put("name", iterationVariableName);
+            map.put("type", paramType);
+            putAt0(positionMapping, i, map);
+        }
         return positionMapping;
     }
 
@@ -211,7 +200,7 @@ public class TailRecursiveASTTransformation extends AbstractASTTransformation {
     }
 
     @SuppressWarnings("Instanceof")
-    private void replaceRecursiveReturnsOutsideClosures(final MethodNode method, final Map<Integer, Map> positionMapping) {
+    private void replaceRecursiveReturnsOutsideClosures(final MethodNode method, final Map<Integer, Map<String, Object>> positionMapping) {
         Closure<Boolean> whenRecursiveReturn = new Closure<Boolean>(this, this) {
             public Boolean doCall(Statement statement, boolean inClosure) {
                 if (inClosure) return false;
@@ -232,14 +221,13 @@ public class TailRecursiveASTTransformation extends AbstractASTTransformation {
             public Statement doCall(ReturnStatement statement) {
                 return new ReturnStatementToIterationConverter().convert(statement, positionMapping);
             }
-
         };
         StatementReplacer replacer = new StatementReplacer(whenRecursiveReturn, replaceWithContinueBlock);
         replacer.replaceIn(method.getCode());
     }
 
     @SuppressWarnings("Instanceof")
-    private void replaceRecursiveReturnsInsideClosures(final MethodNode method, final Map<Integer, Map> positionMapping) {
+    private void replaceRecursiveReturnsInsideClosures(final MethodNode method, final Map<Integer, Map<String, Object>> positionMapping) {
         Closure<Boolean> whenRecursiveReturn = new Closure<Boolean>(this, this) {
             public Boolean doCall(Statement statement, boolean inClosure) {
                 if (!inClosure) return false;
@@ -254,13 +242,11 @@ public class TailRecursiveASTTransformation extends AbstractASTTransformation {
 
                 return isRecursiveIn(inner, method);
             }
-
         };
         Closure<Statement> replaceWithThrowLoopException = new Closure<Statement>(this, this) {
             public Statement doCall(ReturnStatement statement) {
                 return new ReturnStatementToIterationConverter(AstHelper.recurByThrowStatement()).convert(statement, positionMapping);
             }
-
         };
         StatementReplacer replacer = new StatementReplacer(whenRecursiveReturn, replaceWithThrowLoopException);
         replacer.replaceIn(method.getCode());
@@ -280,7 +266,6 @@ public class TailRecursiveASTTransformation extends AbstractASTTransformation {
         for (Expression expression : remainingRecursiveCalls) {
             addError("Recursive call could not be transformed by @TailRecursive. Maybe it's not a tail call.", expression);
         }
-
     }
 
     private boolean hasRecursiveMethodCalls(MethodNode method) {
diff --git a/src/main/java/org/codehaus/groovy/transform/tailrec/TernaryToIfStatementConverter.java b/src/main/java/org/codehaus/groovy/transform/tailrec/TernaryToIfStatementConverter.java
index 8803071..9a092b6 100644
--- a/src/main/java/org/codehaus/groovy/transform/tailrec/TernaryToIfStatementConverter.java
+++ b/src/main/java/org/codehaus/groovy/transform/tailrec/TernaryToIfStatementConverter.java
@@ -24,7 +24,6 @@ import org.codehaus.groovy.ast.stmt.Statement;
 
 import static org.codehaus.groovy.ast.tools.GeneralUtils.ifElseS;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.returnS;
-import static org.codehaus.groovy.runtime.DefaultGroovyMethods.asType;
 
 /**
  * Since a ternary statement has more than one exit point tail-recursiveness testing cannot be easily done.
@@ -35,7 +34,7 @@ public class TernaryToIfStatementConverter {
     public Statement convert(ReturnStatement statementWithInnerTernaryExpression) {
         if (!(statementWithInnerTernaryExpression.getExpression() instanceof TernaryExpression))
             return statementWithInnerTernaryExpression;
-        TernaryExpression ternary = asType(statementWithInnerTernaryExpression.getExpression(), TernaryExpression.class);
+        TernaryExpression ternary = (TernaryExpression) statementWithInnerTernaryExpression.getExpression();
         return ifElseS(ternary.getBooleanExpression(), returnS(ternary.getTrueExpression()), returnS(ternary.getFalseExpression()));
     }
 }
diff --git a/src/main/java/org/codehaus/groovy/transform/tailrec/VariableExpressionReplacer.java b/src/main/java/org/codehaus/groovy/transform/tailrec/VariableExpressionReplacer.java
index ad73fcb..c115bb5 100644
--- a/src/main/java/org/codehaus/groovy/transform/tailrec/VariableExpressionReplacer.java
+++ b/src/main/java/org/codehaus/groovy/transform/tailrec/VariableExpressionReplacer.java
@@ -39,7 +39,6 @@ import org.codehaus.groovy.ast.stmt.SynchronizedStatement;
 import org.codehaus.groovy.ast.stmt.ThrowStatement;
 import org.codehaus.groovy.ast.stmt.WhileStatement;
 import org.codehaus.groovy.ast.tools.GeneralUtils;
-import org.codehaus.groovy.runtime.DefaultGroovyMethods;
 
 import java.lang.reflect.Method;
 
@@ -182,7 +181,7 @@ public class VariableExpressionReplacer extends CodeVisitorSupport {
             //Use reflection to enable CompileStatic
             String getterName = GeneralUtils.getGetterName(propName);
             Method getExpressionMethod = node.getClass().getMethod(getterName);
-            return DefaultGroovyMethods.asType(getExpressionMethod.invoke(node), Expression.class);
+            return (Expression) getExpressionMethod.invoke(node);
         } catch (Throwable t) {
             UncheckedThrow.rethrow(t);
             return null;