Commits

Tim Vernum committed 08eb930

Refactor methods from Convert7To8Visitor into ArrayUtil and LambdaConverter

Comments (0)

Files changed (4)

 ^[a-z]*-samples/
 ^[a-z]*/.*\.iml
 ^lib/
+^[^/]*\.java$
 \.class$
 ^wiki/
 

convert/source/java/main/org/adjective/syntactic/convert/j7to8/Convert7To8Visitor.java

  */
 package org.adjective.syntactic.convert.j7to8;
 
-import org.adjective.syntactic.convert.j7to8.type.MethodInfo;
-import org.adjective.syntactic.convert.j7to8.type.TypeInfo;
 import org.adjective.syntactic.convert.j7to8.util.ClassFinder;
 import org.adjective.syntactic.convert.j7to8.util.Importer;
 import org.adjective.syntactic.convert.j7to8.util.VariableStack;
+import org.adjective.syntactic.parser.ast.*;
 import org.adjective.syntactic.parser.node.BaseNode;
-import org.adjective.syntactic.parser.util.DefaultVisitor;
-import org.adjective.syntactic.parser.ast.*;
-import org.adjective.syntactic.parser.name.ParameterizedName;
-import org.adjective.syntactic.parser.name.SimpleParameterizedName;
-import org.adjective.syntactic.parser.name.SimpleTypeParameter;
-import org.adjective.syntactic.parser.name.TypeParameter;
 import org.adjective.syntactic.parser.node.ExpressionNode;
 import org.adjective.syntactic.parser.node.StatementNode;
 import org.adjective.syntactic.parser.node.VariableDeclarationNode;
 import org.adjective.syntactic.parser.type.JavaType;
-import org.adjective.syntactic.parser.type.SimpleJavaType;
-import org.adjective.syntactic.parser.util.*;
+import org.adjective.syntactic.parser.util.DefaultVisitor;
+import org.adjective.syntactic.parser.util.ModifierSet;
 import org.adjective.syntactic.parser.util.Pair;
 
-import java.lang.reflect.Method;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Stack;
 
-public class    Convert7To8Visitor extends DefaultVisitor<Object, Object>
+public class Convert7To8Visitor extends DefaultVisitor<Object, Object>
 {
     private final Stack<String> _className;
     private final VariableStack _vars;
     private final ClassFinder _classFinder;
     private final Importer _importer;
+    private final LambdaConverter _lambdaConverter;
     private final List<Pair<VariableDeclarationNode, String>> _toMarkFinal;
 
     public Convert7To8Visitor()
         _vars = new VariableStack();
         _classFinder = new ClassFinder();
         _importer = new Importer(_classFinder);
+        _lambdaConverter = new LambdaConverter(_importer, _classFinder);
         _toMarkFinal = new ArrayList<Pair<VariableDeclarationNode, String>>();
     }
 
             }
 
             final ASTLambdaExpression lambda = expr.as(ASTLambdaExpression.class);
-            final ExpressionNode convert = convertLambda(lambda,
-                                                         getType(node, var));
+            final ExpressionNode convert = _lambdaConverter.convertLambda(lambda,
+                                                                          getType(node, var));
             fixBody(lambda.getBody());
             var.replaceInitializer(new ASTExpression(convert));
         }
         return BaseNode.makeType(declaration.getTypeNode(), variable.getArraySuffix());
     }
 
-    private ExpressionNode convertLambda(final ASTLambdaExpression lambda, final JavaType forType)
-    {
-        final ModifierSet set = new ModifierSet(ModifierSet.Modifier.PUBLIC);
-        final ASTModifiers modifiers = new ASTModifiers(set);
-        final TypeInfo typeInfo = getTypeInfo(forType);
-        final MethodInfo methodInfo = getFunctionalMethod(typeInfo);
-        final ASTMethodDeclaration astMethod = makeMethodDeclaration(methodInfo,
-                                                                     lambda.getParameters(),
-                                                                     lambda.getBody());
-        final ASTMember member = new ASTMember(modifiers, astMethod);
-        ASTClassOrInterfaceBody body = new ASTClassOrInterfaceBody(new ASTClassOrInterfaceBodyElement(member));
-        final JavaType astType = substituteType(astMethod.getParameters(), methodInfo, forType);
-        return new ASTAllocationExpression(withoutWildcard(astType), new ASTArguments(), body);
-    }
-
-    private JavaType substituteType(final ASTFormalParameters parameters, final MethodInfo method, final JavaType type)
-    {
-        final Integer[] typeParameters = method.getClassTypeParameters();
-        if (isNull(typeParameters))
-        {
-            return type;
-        }
-        final ParameterizedName lastName = last(type.getParameterizedTypeName());
-        TypeParameter[] classParameters = Arrays.copyOf(lastName.getParameters(), lastName.getParameters().length);
-        for (int i = 0; i < typeParameters.length; i++)
-        {
-            final Integer classIndex = typeParameters[i];
-            if (classIndex != null)
-            {
-                classParameters[classIndex] = new SimpleTypeParameter(TypeParameter.Kind.EXACT,
-                                                                     parameters.getParameterTypes()[i]);
-            }
-        }
-
-        ParameterizedName[] name = new ParameterizedName[type.getParameterizedTypeName().length];
-        System.arraycopy(type.getParameterizedTypeName(), 0, name, 0, name.length - 1);
-        name[name.length - 1] = new SimpleParameterizedName(lastName.getName(), classParameters);
-        return new SimpleJavaType(name, type.getArrayDepth());
-    }
-
-    private boolean isNull(final Object[] array)
-    {
-        for (Object o : array)
-        {
-            if(o != null) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    private JavaType withoutWildcard(final JavaType forType)
-    {
-        if (!hasWildcard(forType))
-        {
-            return forType;
-        }
-        final ParameterizedName[] inputName = forType.getParameterizedTypeName();
-        final ParameterizedName[] outputName = new ParameterizedName[inputName.length];
-        for (int i = 0; i < inputName.length; i++)
-        {
-            ParameterizedName parameterizedName = inputName[i];
-            final TypeParameter[] inputParameters = parameterizedName.getParameters();
-            if (inputParameters.length == 0)
-            {
-                outputName[i] = parameterizedName;
-                continue;
-            }
-            final TypeParameter[] outputParameters = new TypeParameter[inputParameters.length];
-            for (int j = 0; j < outputParameters.length; j++)
-            {
-                outputParameters[j] = new SimpleTypeParameter(TypeParameter.Kind.EXACT, inputParameters[j].getType());
-            }
-            outputName[i] = new SimpleParameterizedName(inputName[i].getName(), outputParameters);
-        }
-        return new SimpleJavaType(outputName, forType.getArrayDepth());
-    }
-
-    private boolean hasWildcard(final JavaType forType)
-    {
-        final TypeParameter[] parameters = last(forType.getParameterizedTypeName()).getParameters();
-        for (int i = 0; i < parameters.length; i++)
-        {
-            if (parameters[i].getKind() != TypeParameter.Kind.EXACT)
-            {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private ASTMethodDeclaration makeMethodDeclaration(final MethodInfo method, final ASTLambdaParameters parameters, final ASTLambdaBody lambdaBody)
-    {
-        final ASTMethodBody body = getMethodBody(lambdaBody);
-        final ASTNameList exceptions = method.getExceptionTypes().length == 0 ? null
-                : new ASTNameList(method.getExceptionTypes());
-        return new ASTMethodDeclaration(method.getReturnType(),
-                                        new ASTIdentifier(method.getName()),
-                                        makeFormalParameters(method, parameters),
-                                        new ASTArraySuffixList(),
-                                        exceptions,
-                                        body);
-    }
-
-    private MethodInfo getFunctionalMethod(final TypeInfo typeInfo)
-    {
-        final Collection<MethodInfo> methods = filterMethods(typeInfo.getMethods());
-        if (methods.size() != 1)
-        {
-            throw new ConversionException("Class '" + typeInfo.getName() + "' should have exactly 1 method but has " + methods
-                    .size());
-        }
-
-        return methods.iterator().next();
-    }
-
-    private TypeInfo getTypeInfo(final JavaType forType)
-    {
-        String name = forType.getTypeName();
-        if (forType.getParameterizedTypeName().length == 1)
-        {
-            String qN = _importer.getQualifiedName(name);
-            if (qN != null)
-            {
-                name = qN;
-            }
-        }
-
-        final TypeInfo typeInfo = _classFinder.getClass(name, last(forType.getParameterizedTypeName()).getParameters());
-        if (typeInfo == null)
-        {
-            throw new ConversionException("Cannot find '" + name + "'");
-        }
-        return typeInfo;
-    }
-
-    private ASTMethodBody getMethodBody(final ASTLambdaBody lambdaBody)
-    {
-        ASTBlock block;
-        if (lambdaBody.isExpression())
-        {
-            ASTReturnStatement stmt = new ASTReturnStatement(lambdaBody.getExpression());
-            block = new ASTBlock(stmt);
-        }
-        else
-        {
-            block = lambdaBody.getBlock();
-        }
-        return new ASTMethodBody(block);
-    }
-
-    private <T> T last(T[] array)
-    {
-        return array[array.length - 1];
-    }
-
-    private Collection<MethodInfo> filterMethods(final MethodInfo[] methods)
-    {
-        Collection<MethodInfo> filter = new ArrayList<MethodInfo>(1);
-        for (int i = 0; i < methods.length; i++)
-        {
-            if (!isObjectMethod(methods[i]))
-            {
-                filter.add(methods[i]);
-            }
-        }
-        return filter;
-    }
-
-    private boolean isObjectMethod(MethodInfo method)
-    {
-        final Method[] objectMethods = Object.class.getMethods();
-        for (int i = 0; i < objectMethods.length; i++)
-        {
-            Method objectMethod = objectMethods[i];
-            if (isMatchingMethod(objectMethod, method))
-            {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private boolean isMatchingMethod(final Method objectMethod, final MethodInfo method)
-    {
-        if (!objectMethod.getName().equals(method.getName()))
-        {
-            return false;
-        }
-        if (objectMethod.getParameterTypes().length != method.getParameterTypes().length)
-        {
-            return false;
-        }
-        for (int i = 0; i < objectMethod.getParameterTypes().length; i++)
-        {
-            if (!isMatchingType(objectMethod.getParameterTypes()[i], method.getParameterTypes()[i]))
-            {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    private boolean isMatchingType(final Class<?> cls, final JavaType type)
-    {
-        return cls.getName().equals(type.getTypeName());
-    }
-
-    private ASTFormalParameters makeFormalParameters(final MethodInfo method, final ASTLambdaParameters parameters)
-    {
-        final JavaType[] parameterTypes;
-        if (parameters.hasDeclaredParameterTypes())
-        {
-            parameterTypes = parameters.getParameterListNode().getParameterTypes();
-        }
-        else
-        {
-            parameterTypes = method.getParameterTypes();
-        }
-        final String[] parameterNames = new String[parameterTypes.length];
-        final Iterator<ASTIdentifier> iterator = parameters.getParameterNames().iterator();
-        for (int i = 0; i < parameterNames.length; i++)
-        {
-            if (iterator.hasNext())
-            {
-                parameterNames[i] = iterator.next().getIdentifier();
-            }
-            else
-            {
-                throw new ConversionException("Incorrect number of arguments to " + method + " - " + parameterNames.length + " expected");
-            }
-        }
-        ASTFormalParameter[] formalParameters = new ASTFormalParameter[parameterTypes.length];
-        for (int i = 0; i < formalParameters.length; i++)
-        {
-            formalParameters[i] = new ASTFormalParameter(parameterTypes[i],
-                                                         i == formalParameters.length - 1 && method.isVarArgs(),
-                                                         parameterNames[i]);
-        }
-        return new ASTFormalParameters(formalParameters);
-    }
 }

convert/source/java/main/org/adjective/syntactic/convert/j7to8/LambdaConverter.java

+/* ------------------------------------------------------------------------
+ * Copyright 2013 Tim Vernum
+ * ------------------------------------------------------------------------
+ * Licensed 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.adjective.syntactic.convert.j7to8;
+
+import org.adjective.syntactic.convert.j7to8.type.MethodInfo;
+import org.adjective.syntactic.convert.j7to8.type.TypeInfo;
+import org.adjective.syntactic.convert.j7to8.util.ArrayUtil;
+import org.adjective.syntactic.convert.j7to8.util.ClassFinder;
+import org.adjective.syntactic.convert.j7to8.util.Importer;
+import org.adjective.syntactic.parser.ast.*;
+import org.adjective.syntactic.parser.name.ParameterizedName;
+import org.adjective.syntactic.parser.name.SimpleParameterizedName;
+import org.adjective.syntactic.parser.name.SimpleTypeParameter;
+import org.adjective.syntactic.parser.name.TypeParameter;
+import org.adjective.syntactic.parser.node.ExpressionNode;
+import org.adjective.syntactic.parser.type.JavaType;
+import org.adjective.syntactic.parser.type.SimpleJavaType;
+import org.adjective.syntactic.parser.util.ModifierSet;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+
+public class LambdaConverter
+{
+    private final Importer _importer;
+    private final ClassFinder _classFinder;
+
+    public LambdaConverter(final Importer importer, final ClassFinder classFinder)
+    {
+        _classFinder = classFinder;
+        _importer = importer;
+    }
+
+    public ExpressionNode convertLambda(final ASTLambdaExpression lambda, final JavaType forType)
+    {
+        final ModifierSet set = new ModifierSet(ModifierSet.Modifier.PUBLIC);
+        final ASTModifiers modifiers = new ASTModifiers(set);
+        final TypeInfo typeInfo = getTypeInfo(forType);
+        final MethodInfo methodInfo = getFunctionalMethod(typeInfo);
+        final ASTMethodDeclaration astMethod = makeMethodDeclaration(methodInfo,
+                                                                     lambda.getParameters(),
+                                                                     lambda.getBody());
+        final ASTMember member = new ASTMember(modifiers, astMethod);
+        ASTClassOrInterfaceBody body = new ASTClassOrInterfaceBody(new ASTClassOrInterfaceBodyElement(member));
+        final JavaType astType = substituteType(astMethod.getParameters(), methodInfo, forType);
+        return new ASTAllocationExpression(withoutWildcard(astType), new ASTArguments(), body);
+    }
+
+    private TypeInfo getTypeInfo(final JavaType forType)
+    {
+        String name = forType.getTypeName();
+        if (forType.getParameterizedTypeName().length == 1)
+        {
+            String qN = _importer.getQualifiedName(name);
+            if (qN != null)
+            {
+                name = qN;
+            }
+        }
+
+        final TypeInfo typeInfo = _classFinder.getClass(name,
+                                                        ArrayUtil.last(forType.getParameterizedTypeName())
+                                                                .getParameters());
+        if (typeInfo == null)
+        {
+            throw new ConversionException("Cannot find '" + name + "'");
+        }
+        return typeInfo;
+    }
+
+    private MethodInfo getFunctionalMethod(final TypeInfo typeInfo)
+    {
+        final Collection<MethodInfo> methods = filterMethods(typeInfo.getMethods());
+        if (methods.size() != 1)
+        {
+            throw new ConversionException("Class '" + typeInfo.getName() + "' should have exactly 1 method but has " + methods
+                    .size());
+        }
+
+        return methods.iterator().next();
+    }
+
+    private ASTMethodDeclaration makeMethodDeclaration(final MethodInfo method, final ASTLambdaParameters parameters, final ASTLambdaBody lambdaBody)
+    {
+        final ASTMethodBody body = getMethodBody(lambdaBody);
+        final ASTNameList exceptions = method.getExceptionTypes().length == 0 ? null
+                : new ASTNameList(method.getExceptionTypes());
+        return new ASTMethodDeclaration(method.getReturnType(),
+                                        new ASTIdentifier(method.getName()),
+                                        makeFormalParameters(method, parameters),
+                                        new ASTArraySuffixList(),
+                                        exceptions,
+                                        body);
+    }
+
+    private JavaType substituteType(final ASTFormalParameters parameters, final MethodInfo method, final JavaType type)
+    {
+        final Integer[] typeParameters = method.getClassTypeParameters();
+        if (ArrayUtil.isNull(typeParameters))
+        {
+            return type;
+        }
+        final ParameterizedName lastName = ArrayUtil.last(type.getParameterizedTypeName());
+        TypeParameter[] classParameters = Arrays.copyOf(lastName.getParameters(), lastName.getParameters().length);
+        for (int i = 0; i < typeParameters.length; i++)
+        {
+            final Integer classIndex = typeParameters[i];
+            if (classIndex != null)
+            {
+                classParameters[classIndex] = new SimpleTypeParameter(TypeParameter.Kind.EXACT,
+                                                                      parameters.getParameterTypes()[i]);
+            }
+        }
+
+        ParameterizedName[] name = new ParameterizedName[type.getParameterizedTypeName().length];
+        System.arraycopy(type.getParameterizedTypeName(), 0, name, 0, name.length - 1);
+        name[name.length - 1] = new SimpleParameterizedName(lastName.getName(), classParameters);
+        return new SimpleJavaType(name, type.getArrayDepth());
+    }
+
+    private JavaType withoutWildcard(final JavaType forType)
+    {
+        if (!hasWildcard(forType))
+        {
+            return forType;
+        }
+        final ParameterizedName[] inputName = forType.getParameterizedTypeName();
+        final ParameterizedName[] outputName = new ParameterizedName[inputName.length];
+        for (int i = 0; i < inputName.length; i++)
+        {
+            ParameterizedName parameterizedName = inputName[i];
+            final TypeParameter[] inputParameters = parameterizedName.getParameters();
+            if (inputParameters.length == 0)
+            {
+                outputName[i] = parameterizedName;
+                continue;
+            }
+            final TypeParameter[] outputParameters = new TypeParameter[inputParameters.length];
+            for (int j = 0; j < outputParameters.length; j++)
+            {
+                outputParameters[j] = new SimpleTypeParameter(TypeParameter.Kind.EXACT, inputParameters[j].getType());
+            }
+            outputName[i] = new SimpleParameterizedName(inputName[i].getName(), outputParameters);
+        }
+        return new SimpleJavaType(outputName, forType.getArrayDepth());
+    }
+
+    private boolean hasWildcard(final JavaType forType)
+    {
+        final TypeParameter[] parameters = ArrayUtil.last(forType.getParameterizedTypeName()).getParameters();
+        for (final TypeParameter parameter : parameters)
+        {
+            if (parameter.getKind() != TypeParameter.Kind.EXACT)
+            {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private Collection<MethodInfo> filterMethods(final MethodInfo[] methods)
+    {
+        Collection<MethodInfo> filter = new ArrayList<MethodInfo>(1);
+        for (final MethodInfo method : methods)
+        {
+            if (!isObjectMethod(method))
+            {
+                filter.add(method);
+            }
+        }
+        return filter;
+    }
+
+    private boolean isObjectMethod(MethodInfo method)
+    {
+        final Method[] objectMethods = Object.class.getMethods();
+        for (Method objectMethod : objectMethods)
+        {
+            if (isMatchingMethod(objectMethod, method))
+            {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private boolean isMatchingMethod(final Method objectMethod, final MethodInfo method)
+    {
+        if (!objectMethod.getName().equals(method.getName()))
+        {
+            return false;
+        }
+        if (objectMethod.getParameterTypes().length != method.getParameterTypes().length)
+        {
+            return false;
+        }
+        for (int i = 0; i < objectMethod.getParameterTypes().length; i++)
+        {
+            if (!isMatchingType(objectMethod.getParameterTypes()[i], method.getParameterTypes()[i]))
+            {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    private boolean isMatchingType(final Class<?> cls, final JavaType type)
+    {
+        return cls.getName().equals(type.getTypeName());
+    }
+
+    private ASTFormalParameters makeFormalParameters(final MethodInfo method, final ASTLambdaParameters parameters)
+    {
+        final JavaType[] parameterTypes;
+        if (parameters.hasDeclaredParameterTypes())
+        {
+            parameterTypes = parameters.getParameterListNode().getParameterTypes();
+        }
+        else
+        {
+            parameterTypes = method.getParameterTypes();
+        }
+        final String[] parameterNames = new String[parameterTypes.length];
+        final Iterator<ASTIdentifier> iterator = parameters.getParameterNames().iterator();
+        for (int i = 0; i < parameterNames.length; i++)
+        {
+            if (iterator.hasNext())
+            {
+                parameterNames[i] = iterator.next().getIdentifier();
+            }
+            else
+            {
+                throw new ConversionException("Incorrect number of arguments to " + method + " - " + parameterNames.length + " expected");
+            }
+        }
+        ASTFormalParameter[] formalParameters = new ASTFormalParameter[parameterTypes.length];
+        for (int i = 0; i < formalParameters.length; i++)
+        {
+            formalParameters[i] = new ASTFormalParameter(parameterTypes[i],
+                                                         i == formalParameters.length - 1 && method.isVarArgs(),
+                                                         parameterNames[i]);
+        }
+        return new ASTFormalParameters(formalParameters);
+    }
+
+    private ASTMethodBody getMethodBody(final ASTLambdaBody lambdaBody)
+    {
+        ASTBlock block;
+        if (lambdaBody.isExpression())
+        {
+            ASTReturnStatement stmt = new ASTReturnStatement(lambdaBody.getExpression());
+            block = new ASTBlock(stmt);
+        }
+        else
+        {
+            block = lambdaBody.getBlock();
+        }
+        return new ASTMethodBody(block);
+    }
+}

convert/source/java/main/org/adjective/syntactic/convert/j7to8/util/ArrayUtil.java

+/* ------------------------------------------------------------------------
+ * Copyright 2013 Tim Vernum
+ * ------------------------------------------------------------------------
+ * Licensed 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.adjective.syntactic.convert.j7to8.util;
+
+public class ArrayUtil
+{
+    public static boolean isNull(final Object[] array)
+    {
+        for (Object o : array)
+        {
+            if (o != null)
+            {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    public static <T> T last(T[] array)
+    {
+        return array[array.length - 1];
+    }
+}