Search in sources :

Example 71 with Parameter

use of org.codehaus.groovy.ast.Parameter in project groovy by apache.

the class StaticInvocationWriter method loadArguments.

@Override
protected void loadArguments(final List<Expression> argumentList, final Parameter[] parameters) {
    final int nArgs = argumentList.size(), nPrms = parameters.length;
    if (nPrms == 0)
        return;
    ClassNode classNode = controller.getClassNode();
    TypeChooser typeChooser = controller.getTypeChooser();
    ClassNode lastArgType = nArgs == 0 ? null : typeChooser.resolveType(argumentList.get(nArgs - 1), classNode);
    ClassNode lastPrmType = parameters[nPrms - 1].getOriginType();
    // target is variadic and args are too many or one short or just enough with array compatibility
    if (lastPrmType.isArray() && (nArgs > nPrms || nArgs == nPrms - 1 || (nArgs == nPrms && !lastArgType.isArray() && (StaticTypeCheckingSupport.implementsInterfaceOrIsSubclassOf(lastArgType, lastPrmType.getComponentType()) || isGStringType(lastArgType) && isStringType(lastPrmType.getComponentType()))))) {
        OperandStack operandStack = controller.getOperandStack();
        int stackLength = operandStack.getStackLength() + nArgs;
        // first arguments/parameters as usual
        for (int i = 0; i < nPrms - 1; i += 1) {
            visitArgument(argumentList.get(i), parameters[i].getType());
        }
        // wrap remaining arguments in an array for last parameter
        List<Expression> lastArgs = new ArrayList<>();
        for (int i = nPrms - 1; i < nArgs; i += 1) {
            lastArgs.add(argumentList.get(i));
        }
        ArrayExpression array = new ArrayExpression(lastPrmType.getComponentType(), lastArgs);
        array.visit(controller.getAcg());
        // adjust stack length
        while (operandStack.getStackLength() < stackLength) {
            operandStack.push(ClassHelper.OBJECT_TYPE);
        }
        if (nArgs == nPrms - 1) {
            operandStack.remove(1);
        }
    } else if (nArgs == nPrms) {
        for (int i = 0; i < nArgs; i += 1) {
            visitArgument(argumentList.get(i), parameters[i].getType());
        }
    } else {
        // call with default arguments
        Expression[] arguments = new Expression[nPrms];
        for (int i = 0, j = 0; i < nPrms; i += 1) {
            Parameter p = parameters[i];
            ClassNode pType = p.getType();
            Expression a = (j < nArgs ? argumentList.get(j) : null);
            ClassNode aType = (a == null ? null : typeChooser.resolveType(a, classNode));
            // default argument
            Expression expression = getInitialExpression(p);
            if (expression != null && !isCompatibleArgumentType(aType, pType)) {
                arguments[i] = expression;
            } else if (a != null) {
                arguments[i] = a;
                j += 1;
            } else {
                controller.getSourceUnit().addFatalError("Binding failed" + " for arguments [" + argumentList.stream().map(arg -> typeChooser.resolveType(arg, classNode).toString(false)).collect(Collectors.joining(", ")) + "]" + " and parameters [" + Arrays.stream(parameters).map(prm -> prm.getType().toString(false)).collect(Collectors.joining(", ")) + "]", getCurrentCall());
            }
        }
        for (int i = 0; i < nArgs; i += 1) {
            visitArgument(arguments[i], parameters[i].getType());
        }
    }
}
Also used : OperandStack(org.codehaus.groovy.classgen.asm.OperandStack) Traits.isTrait(org.codehaus.groovy.transform.trait.Traits.isTrait) Arrays(java.util.Arrays) GeneralUtils.stmt(org.codehaus.groovy.ast.tools.GeneralUtils.stmt) MethodVisitor(org.objectweb.asm.MethodVisitor) ClassHelper.isGStringType(org.codehaus.groovy.ast.ClassHelper.isGStringType) WriterController(org.codehaus.groovy.classgen.asm.WriterController) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) GeneralUtils.classX(org.codehaus.groovy.ast.tools.GeneralUtils.classX) InvocationWriter(org.codehaus.groovy.classgen.asm.InvocationWriter) BytecodeHelper(org.codehaus.groovy.classgen.asm.BytecodeHelper) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) GeneralUtils.nullX(org.codehaus.groovy.ast.tools.GeneralUtils.nullX) Map(java.util.Map) GeneralUtils.propX(org.codehaus.groovy.ast.tools.GeneralUtils.propX) StaticTypeCheckingVisitor(org.codehaus.groovy.transform.stc.StaticTypeCheckingVisitor) GeneralUtils.ctorX(org.codehaus.groovy.ast.tools.GeneralUtils.ctorX) ForStatement(org.codehaus.groovy.ast.stmt.ForStatement) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) ArrayExpression(org.codehaus.groovy.ast.expr.ArrayExpression) GeneralUtils.args(org.codehaus.groovy.ast.tools.GeneralUtils.args) IFNULL(org.objectweb.asm.Opcodes.IFNULL) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) MethodCallerMultiAdapter(org.codehaus.groovy.classgen.asm.MethodCallerMultiAdapter) ExpressionUtils.isThisOrSuper(org.apache.groovy.ast.tools.ExpressionUtils.isThisOrSuper) DecompiledClassNode(org.codehaus.groovy.ast.decompiled.DecompiledClassNode) ClassHelper.isPrimitiveVoid(org.codehaus.groovy.ast.ClassHelper.isPrimitiveVoid) Collectors(java.util.stream.Collectors) GeneralUtils.callX(org.codehaus.groovy.ast.tools.GeneralUtils.callX) InnerClassNode(org.codehaus.groovy.ast.InnerClassNode) CallSiteWriter(org.codehaus.groovy.classgen.asm.CallSiteWriter) StaticCompilationVisitor(org.codehaus.groovy.transform.sc.StaticCompilationVisitor) List(java.util.List) CompileStack(org.codehaus.groovy.classgen.asm.CompileStack) ExpressionAsVariableSlot(org.codehaus.groovy.classgen.asm.ExpressionAsVariableSlot) GroovyCodeVisitor(org.codehaus.groovy.ast.GroovyCodeVisitor) ClassNodeUtils.samePackageName(org.apache.groovy.ast.tools.ClassNodeUtils.samePackageName) GOTO(org.objectweb.asm.Opcodes.GOTO) GeneralUtils.constX(org.codehaus.groovy.ast.tools.GeneralUtils.constX) PropertyExpression(org.codehaus.groovy.ast.expr.PropertyExpression) ExpressionUtils.isSuperExpression(org.apache.groovy.ast.tools.ExpressionUtils.isSuperExpression) Label(org.objectweb.asm.Label) Verifier(org.codehaus.groovy.classgen.Verifier) ArrayList(java.util.ArrayList) ExtensionMethodNode(org.codehaus.groovy.transform.stc.ExtensionMethodNode) INVOKESTATIC(org.objectweb.asm.Opcodes.INVOKESTATIC) MethodNode(org.codehaus.groovy.ast.MethodNode) ACONST_NULL(org.objectweb.asm.Opcodes.ACONST_NULL) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) GeneralUtils.varX(org.codehaus.groovy.ast.tools.GeneralUtils.varX) Expression(org.codehaus.groovy.ast.expr.Expression) StaticTypeCheckingSupport(org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport) ExpressionUtils.isNullConstant(org.apache.groovy.ast.tools.ExpressionUtils.isNullConstant) CHECKCAST(org.objectweb.asm.Opcodes.CHECKCAST) Parameter(org.codehaus.groovy.ast.Parameter) ConstructorCallExpression(org.codehaus.groovy.ast.expr.ConstructorCallExpression) InvokerHelper(org.codehaus.groovy.runtime.InvokerHelper) ClassNode(org.codehaus.groovy.ast.ClassNode) OperandStack(org.codehaus.groovy.classgen.asm.OperandStack) ClassHelper(org.codehaus.groovy.ast.ClassHelper) ClassHelper.isStringType(org.codehaus.groovy.ast.ClassHelper.isStringType) AsmClassGenerator(org.codehaus.groovy.classgen.AsmClassGenerator) StaticCompilationMetadataKeys(org.codehaus.groovy.transform.sc.StaticCompilationMetadataKeys) TemporaryVariableExpression(org.codehaus.groovy.transform.sc.TemporaryVariableExpression) StaticTypesMarker(org.codehaus.groovy.transform.stc.StaticTypesMarker) TypeChooser(org.codehaus.groovy.classgen.asm.TypeChooser) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) TupleExpression(org.codehaus.groovy.ast.expr.TupleExpression) ExpressionTransformer(org.codehaus.groovy.ast.expr.ExpressionTransformer) FieldNode(org.codehaus.groovy.ast.FieldNode) AttributeExpression(org.codehaus.groovy.ast.expr.AttributeExpression) VariableSlotLoader(org.codehaus.groovy.classgen.asm.VariableSlotLoader) ConstructorNode(org.codehaus.groovy.ast.ConstructorNode) SyntaxException(org.codehaus.groovy.syntax.SyntaxException) ClassHelper.isObjectType(org.codehaus.groovy.ast.ClassHelper.isObjectType) ALOAD(org.objectweb.asm.Opcodes.ALOAD) DecompiledClassNode(org.codehaus.groovy.ast.decompiled.DecompiledClassNode) InnerClassNode(org.codehaus.groovy.ast.InnerClassNode) ClassNode(org.codehaus.groovy.ast.ClassNode) TypeChooser(org.codehaus.groovy.classgen.asm.TypeChooser) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) ArrayExpression(org.codehaus.groovy.ast.expr.ArrayExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) PropertyExpression(org.codehaus.groovy.ast.expr.PropertyExpression) ExpressionUtils.isSuperExpression(org.apache.groovy.ast.tools.ExpressionUtils.isSuperExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) Expression(org.codehaus.groovy.ast.expr.Expression) ConstructorCallExpression(org.codehaus.groovy.ast.expr.ConstructorCallExpression) TemporaryVariableExpression(org.codehaus.groovy.transform.sc.TemporaryVariableExpression) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) TupleExpression(org.codehaus.groovy.ast.expr.TupleExpression) AttributeExpression(org.codehaus.groovy.ast.expr.AttributeExpression) ArrayList(java.util.ArrayList) ArrayExpression(org.codehaus.groovy.ast.expr.ArrayExpression) Parameter(org.codehaus.groovy.ast.Parameter)

Example 72 with Parameter

use of org.codehaus.groovy.ast.Parameter in project groovy by apache.

the class InvocationWriter method writeAICCall.

protected boolean writeAICCall(final ConstructorCallExpression call) {
    if (!call.isUsingAnonymousInnerClass())
        return false;
    ConstructorNode cn = call.getType().getDeclaredConstructors().get(0);
    OperandStack os = controller.getOperandStack();
    String ownerDescriptor = prepareConstructorCall(cn);
    List<Expression> args = makeArgumentList(call.getArguments()).getExpressions();
    Parameter[] params = cn.getParameters();
    // if a this appears as parameter here, then it should be
    // not static, unless we are in a static method. But since
    // ACG#visitVariableExpression does the opposite for this case, we
    // push here an explicit this. This should not have any negative effect
    // sine visiting a method call or property with implicit this will push
    // a new value for this again.
    controller.getCompileStack().pushImplicitThis(true);
    for (int i = 0, n = params.length; i < n; i += 1) {
        Parameter p = params[i];
        Expression arg = args.get(i);
        if (arg instanceof VariableExpression) {
            VariableExpression var = (VariableExpression) arg;
            loadVariableWithReference(var);
        } else {
            arg.visit(controller.getAcg());
        }
        os.doGroovyCast(p.getType());
    }
    controller.getCompileStack().popImplicitThis();
    finnishConstructorCall(cn, ownerDescriptor, args.size());
    return true;
}
Also used : ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) SpreadExpression(org.codehaus.groovy.ast.expr.SpreadExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) ArrayExpression(org.codehaus.groovy.ast.expr.ArrayExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) ExpressionUtils.isThisExpression(org.apache.groovy.ast.tools.ExpressionUtils.isThisExpression) CastExpression(org.codehaus.groovy.ast.expr.CastExpression) PropertyExpression(org.codehaus.groovy.ast.expr.PropertyExpression) StaticMethodCallExpression(org.codehaus.groovy.ast.expr.StaticMethodCallExpression) ExpressionUtils.isSuperExpression(org.apache.groovy.ast.tools.ExpressionUtils.isSuperExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) Expression(org.codehaus.groovy.ast.expr.Expression) ConstructorCallExpression(org.codehaus.groovy.ast.expr.ConstructorCallExpression) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) TupleExpression(org.codehaus.groovy.ast.expr.TupleExpression) ConstructorNode(org.codehaus.groovy.ast.ConstructorNode) Parameter(org.codehaus.groovy.ast.Parameter) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression)

Example 73 with Parameter

use of org.codehaus.groovy.ast.Parameter in project groovy by apache.

the class MopWriter method visitMopMethodList.

/**
 * Filters a list of method for MOP methods. For all methods that are not
 * MOP methods a MOP method is created if the method is not public and the
 * call would be a call on "this" (isThis == true). If the call is not on
 * "this", then the call is a call on "super" and all methods are used,
 * unless they are already a MOP method.
 *
 * @param methods unfiltered list of methods for MOP
 * @param isThis  if true, then we are creating a MOP method on "this", "super" else
 *
 * @see #generateMopCalls(LinkedList, boolean)
 */
private void visitMopMethodList(final Iterable<MethodNode> methods, final boolean isThis, final Set<MopKey> onlyIfThis, final List<String> orThis) {
    LinkedList<MethodNode> list = new LinkedList<>();
    Map<MopKey, MethodNode> map = new HashMap<>();
    for (MethodNode mn : methods) {
        // to the target methods; such a method cannot be abstract or a bridge
        if ((mn.getModifiers() & (ACC_ABSTRACT | ACC_BRIDGE | ACC_STATIC)) != 0)
            continue;
        // --> results in XOR
        if (isThis ^ mn.isPrivate())
            continue;
        String methodName = mn.getName();
        Parameter[] parameters = mn.getParameters();
        if (isMopMethod(methodName)) {
            map.put(new MopKey(methodName, parameters), mn);
        } else if (!methodName.startsWith("<") && (onlyIfThis.contains(new MopKey(methodName, parameters)) || orThis.contains(methodName))) {
            if (map.put(new MopKey(getMopMethodName(mn, isThis), parameters), mn) == null) {
                list.add(mn);
            }
        }
    }
    generateMopCalls(list, isThis);
}
Also used : MethodNode(org.codehaus.groovy.ast.MethodNode) HashMap(java.util.HashMap) Parameter(org.codehaus.groovy.ast.Parameter) LinkedList(java.util.LinkedList)

Example 74 with Parameter

use of org.codehaus.groovy.ast.Parameter in project groovy by apache.

the class MopWriter method generateMopCalls.

/**
 * Generates a Meta Object Protocol method that is used to call a non-public
 * method or to make a call to super.
 *
 * @param methods list of methods a MOP call method should be generated for
 * @param useThis indicates if "this" should be used for the name and call
 */
protected void generateMopCalls(final LinkedList<MethodNode> methods, final boolean useThis) {
    for (MethodNode method : methods) {
        ClassNode returnType = method.getReturnType();
        Parameter[] parameters = method.getParameters();
        String mopName = getMopMethodName(method, useThis);
        String signature = BytecodeHelper.getMethodDescriptor(returnType, parameters);
        MethodVisitor mv = controller.getClassVisitor().visitMethod(ACC_PUBLIC | ACC_SYNTHETIC, mopName, signature, null, null);
        controller.setMethodVisitor(mv);
        int stackIndex = 0;
        // load "this" and the parameters
        mv.visitVarInsn(ALOAD, stackIndex++);
        OperandStack operandStack = controller.getOperandStack();
        for (Parameter parameter : parameters) {
            ClassNode type = parameter.getType();
            operandStack.load(type, stackIndex++);
            if (isPrimitiveLong(type) || isPrimitiveDouble(type))
                // long and double use two slots
                stackIndex += 1;
        }
        operandStack.remove(parameters.length);
        // make call to this or super method with operands
        ClassNode receiverType = controller.getThisType();
        if (!useThis) {
            receiverType = receiverType.getSuperClass();
            ClassNode declaringType = method.getDeclaringClass();
            // GROOVY-8693, GROOVY-9909, et al.: method from interface not implemented by super class
            if (declaringType.isInterface() && !receiverType.implementsInterface(declaringType))
                receiverType = declaringType;
        }
        mv.visitMethodInsn(INVOKESPECIAL, BytecodeHelper.getClassInternalName(receiverType), method.getName(), signature, receiverType.isInterface());
        BytecodeHelper.doReturn(mv, returnType);
        mv.visitMaxs(0, 0);
        mv.visitEnd();
        controller.getClassNode().addMethod(mopName, ACC_PUBLIC | ACC_SYNTHETIC, returnType, parameters, null, null);
    }
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) MethodNode(org.codehaus.groovy.ast.MethodNode) Parameter(org.codehaus.groovy.ast.Parameter) MethodVisitor(org.objectweb.asm.MethodVisitor)

Example 75 with Parameter

use of org.codehaus.groovy.ast.Parameter in project groovy by apache.

the class AbstractFunctionalInterfaceWriter method createBootstrapMethodArguments.

default Object[] createBootstrapMethodArguments(String abstractMethodDesc, int insn, ClassNode methodOwnerClassNode, MethodNode methodNode, boolean serializable) {
    Parameter[] parameters = methodNode.getNodeMetaData(ORIGINAL_PARAMETERS_WITH_EXACT_TYPE);
    List<Object> argumentList = new LinkedList<>();
    argumentList.add(Type.getType(abstractMethodDesc));
    argumentList.add(new Handle(insn, BytecodeHelper.getClassInternalName(methodOwnerClassNode.getName()), methodNode.getName(), BytecodeHelper.getMethodDescriptor(methodNode), methodOwnerClassNode.isInterface()));
    argumentList.add(Type.getType(BytecodeHelper.getMethodDescriptor(methodNode.getReturnType(), parameters)));
    if (serializable) {
        argumentList.add(5);
        argumentList.add(0);
    }
    return argumentList.toArray();
}
Also used : Parameter(org.codehaus.groovy.ast.Parameter) LinkedList(java.util.LinkedList) Handle(org.objectweb.asm.Handle)

Aggregations

Parameter (org.codehaus.groovy.ast.Parameter)342 ClassNode (org.codehaus.groovy.ast.ClassNode)202 MethodNode (org.codehaus.groovy.ast.MethodNode)135 InnerClassNode (org.codehaus.groovy.ast.InnerClassNode)117 BlockStatement (org.codehaus.groovy.ast.stmt.BlockStatement)111 VariableExpression (org.codehaus.groovy.ast.expr.VariableExpression)102 Expression (org.codehaus.groovy.ast.expr.Expression)98 MethodCallExpression (org.codehaus.groovy.ast.expr.MethodCallExpression)90 ArgumentListExpression (org.codehaus.groovy.ast.expr.ArgumentListExpression)75 FieldNode (org.codehaus.groovy.ast.FieldNode)71 ExpressionStatement (org.codehaus.groovy.ast.stmt.ExpressionStatement)71 ClassExpression (org.codehaus.groovy.ast.expr.ClassExpression)69 ConstantExpression (org.codehaus.groovy.ast.expr.ConstantExpression)68 ConstructorNode (org.codehaus.groovy.ast.ConstructorNode)66 ConstructorCallExpression (org.codehaus.groovy.ast.expr.ConstructorCallExpression)66 Statement (org.codehaus.groovy.ast.stmt.Statement)66 ArrayList (java.util.ArrayList)62 ClosureExpression (org.codehaus.groovy.ast.expr.ClosureExpression)56 BinaryExpression (org.codehaus.groovy.ast.expr.BinaryExpression)52 PropertyExpression (org.codehaus.groovy.ast.expr.PropertyExpression)51