Search in sources :

Example 96 with ArgumentListExpression

use of org.codehaus.groovy.ast.expr.ArgumentListExpression in project groovy by apache.

the class SuperCallTraitTransformer method transformMethodCallExpression.

private Expression transformMethodCallExpression(final MethodCallExpression exp) {
    if (isTraitSuperPropertyExpression(exp.getObjectExpression())) {
        Expression objectExpression = exp.getObjectExpression();
        ClassNode traitReceiver = ((PropertyExpression) objectExpression).getObjectExpression().getType();
        if (traitReceiver != null) {
            // (SomeTrait.super).foo() --> SomeTrait$Helper.foo(this)
            ClassExpression receiver = new ClassExpression(getHelper(traitReceiver));
            ArgumentListExpression newArgs = new ArgumentListExpression();
            Expression arguments = exp.getArguments();
            newArgs.addExpression(new VariableExpression("this"));
            if (arguments instanceof TupleExpression) {
                List<Expression> expressions = ((TupleExpression) arguments).getExpressions();
                for (Expression expression : expressions) {
                    newArgs.addExpression(transform(expression));
                }
            } else {
                newArgs.addExpression(transform(arguments));
            }
            MethodCallExpression result = new MethodCallExpression(receiver, transform(exp.getMethod()), newArgs);
            result.setImplicitThis(false);
            result.setSpreadSafe(exp.isSpreadSafe());
            result.setSafe(exp.isSafe());
            result.setSourcePosition(exp);
            return result;
        }
    }
    return super.transform(exp);
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) InnerClassNode(org.codehaus.groovy.ast.InnerClassNode) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) PropertyExpression(org.codehaus.groovy.ast.expr.PropertyExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) TupleExpression(org.codehaus.groovy.ast.expr.TupleExpression) BinaryExpression(org.codehaus.groovy.ast.expr.BinaryExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) Expression(org.codehaus.groovy.ast.expr.Expression) TupleExpression(org.codehaus.groovy.ast.expr.TupleExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression)

Example 97 with ArgumentListExpression

use of org.codehaus.groovy.ast.expr.ArgumentListExpression in project groovy by apache.

the class CallSiteWriter method makeCallSite.

public void makeCallSite(Expression receiver, String message, Expression arguments, boolean safe, boolean implicitThis, boolean callCurrent, boolean callStatic) {
    prepareSiteAndReceiver(receiver, message, implicitThis);
    CompileStack compileStack = controller.getCompileStack();
    compileStack.pushImplicitThis(implicitThis);
    compileStack.pushLHS(false);
    boolean constructor = message.equals(CONSTRUCTOR);
    OperandStack operandStack = controller.getOperandStack();
    // arguments
    boolean containsSpreadExpression = AsmClassGenerator.containsSpreadExpression(arguments);
    int numberOfArguments = containsSpreadExpression ? -1 : AsmClassGenerator.argumentSize(arguments);
    int operandsToReplace = 1;
    if (numberOfArguments > MethodCallerMultiAdapter.MAX_ARGS || containsSpreadExpression) {
        ArgumentListExpression ae;
        if (arguments instanceof ArgumentListExpression) {
            ae = (ArgumentListExpression) arguments;
        } else if (arguments instanceof TupleExpression) {
            TupleExpression te = (TupleExpression) arguments;
            ae = new ArgumentListExpression(te.getExpressions());
        } else {
            ae = new ArgumentListExpression();
            ae.addExpression(arguments);
        }
        controller.getCompileStack().pushImplicitThis(false);
        if (containsSpreadExpression) {
            numberOfArguments = -1;
            controller.getAcg().despreadList(ae.getExpressions(), true);
        } else {
            numberOfArguments = ae.getExpressions().size();
            for (int i = 0; i < numberOfArguments; i++) {
                Expression argument = ae.getExpression(i);
                argument.visit(controller.getAcg());
                operandStack.box();
                if (argument instanceof CastExpression)
                    controller.getAcg().loadWrapper(argument);
            }
            operandsToReplace += numberOfArguments;
        }
        controller.getCompileStack().popImplicitThis();
    }
    controller.getCompileStack().popLHS();
    controller.getCompileStack().popImplicitThis();
    MethodVisitor mv = controller.getMethodVisitor();
    if (numberOfArguments > 4) {
        final String createArraySignature = getCreateArraySignature(numberOfArguments);
        mv.visitMethodInsn(INVOKESTATIC, "org/codehaus/groovy/runtime/ArrayUtil", "createArray", createArraySignature, false);
        //TODO: use pre-generated Object[]
        operandStack.replace(ClassHelper.OBJECT_TYPE.makeArray(), numberOfArguments);
        operandsToReplace = operandsToReplace - numberOfArguments + 1;
    }
    final String desc = getDescForParamNum(numberOfArguments);
    if (callStatic) {
        mv.visitMethodInsn(INVOKEINTERFACE, CALLSITE_CLASS, "callStatic", "(Ljava/lang/Class;" + desc, true);
    } else if (constructor) {
        mv.visitMethodInsn(INVOKEINTERFACE, CALLSITE_CLASS, "callConstructor", "(Ljava/lang/Object;" + desc, true);
    } else if (callCurrent) {
        mv.visitMethodInsn(INVOKEINTERFACE, CALLSITE_CLASS, "callCurrent", "(Lgroovy/lang/GroovyObject;" + desc, true);
    } else if (safe) {
        mv.visitMethodInsn(INVOKEINTERFACE, CALLSITE_CLASS, "callSafe", "(Ljava/lang/Object;" + desc, true);
    } else {
        mv.visitMethodInsn(INVOKEINTERFACE, CALLSITE_CLASS, "call", "(Ljava/lang/Object;" + desc, true);
    }
    operandStack.replace(ClassHelper.OBJECT_TYPE, operandsToReplace);
}
Also used : ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) TupleExpression(org.codehaus.groovy.ast.expr.TupleExpression) CastExpression(org.codehaus.groovy.ast.expr.CastExpression) Expression(org.codehaus.groovy.ast.expr.Expression) TupleExpression(org.codehaus.groovy.ast.expr.TupleExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) CastExpression(org.codehaus.groovy.ast.expr.CastExpression) MethodVisitor(org.objectweb.asm.MethodVisitor)

Example 98 with ArgumentListExpression

use of org.codehaus.groovy.ast.expr.ArgumentListExpression in project groovy by apache.

the class StaticTypesClosureWriter method createDirectCallMethod.

private static void createDirectCallMethod(final ClassNode closureClass, final MethodNode doCallMethod) {
    // in case there is no "call" method on the closure, we can create a "fast invocation" paths
    // to avoid going through ClosureMetaClass by call(Object...) method
    // we can't have a specialized version of call(Object...) because the dispatch logic in ClosureMetaClass
    // is too complex!
    // call(Object)
    Parameter args = new Parameter(ClassHelper.OBJECT_TYPE, "args");
    MethodCallExpression doCall1arg = new MethodCallExpression(new VariableExpression("this", closureClass), "doCall", new ArgumentListExpression(new VariableExpression(args)));
    doCall1arg.setImplicitThis(true);
    doCall1arg.setMethodTarget(doCallMethod);
    closureClass.addMethod(new MethodNode("call", Opcodes.ACC_PUBLIC, ClassHelper.OBJECT_TYPE, new Parameter[] { args }, ClassNode.EMPTY_ARRAY, new ReturnStatement(doCall1arg)));
    // call()
    MethodCallExpression doCallNoArgs = new MethodCallExpression(new VariableExpression("this", closureClass), "doCall", new ArgumentListExpression(new ConstantExpression(null)));
    doCallNoArgs.setImplicitThis(true);
    doCallNoArgs.setMethodTarget(doCallMethod);
    closureClass.addMethod(new MethodNode("call", Opcodes.ACC_PUBLIC, ClassHelper.OBJECT_TYPE, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, new ReturnStatement(doCallNoArgs)));
}
Also used : MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) MethodNode(org.codehaus.groovy.ast.MethodNode) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) ReturnStatement(org.codehaus.groovy.ast.stmt.ReturnStatement) Parameter(org.codehaus.groovy.ast.Parameter) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression)

Example 99 with ArgumentListExpression

use of org.codehaus.groovy.ast.expr.ArgumentListExpression in project groovy by apache.

the class StaticTypesStatementWriter method writeIteratorBasedForEachLoop.

private void writeIteratorBasedForEachLoop(CompileStack compileStack, OperandStack operandStack, MethodVisitor mv, ForStatement loop, Expression collectionExpression, ClassNode collectionType, Parameter loopVariable) {
    // Declare the loop counter.
    BytecodeVariable variable = compileStack.defineVariable(loopVariable, false);
    if (StaticTypeCheckingSupport.implementsInterfaceOrIsSubclassOf(collectionType, ITERABLE_CLASSNODE)) {
        MethodCallExpression iterator = new MethodCallExpression(collectionExpression, "iterator", new ArgumentListExpression());
        iterator.setMethodTarget(collectionType.getMethod("iterator", Parameter.EMPTY_ARRAY));
        iterator.setImplicitThis(false);
        iterator.visit(controller.getAcg());
    } else {
        collectionExpression.visit(controller.getAcg());
        mv.visitMethodInsn(INVOKESTATIC, "org/codehaus/groovy/runtime/DefaultGroovyMethods", "iterator", "(Ljava/lang/Object;)Ljava/util/Iterator;", false);
        operandStack.replace(ClassHelper.Iterator_TYPE);
    }
    // Then get the iterator and generate the loop control
    int iteratorIdx = compileStack.defineTemporaryVariable("iterator", ClassHelper.Iterator_TYPE, true);
    Label continueLabel = compileStack.getContinueLabel();
    Label breakLabel = compileStack.getBreakLabel();
    mv.visitLabel(continueLabel);
    mv.visitVarInsn(ALOAD, iteratorIdx);
    writeIteratorHasNext(mv);
    // note: ifeq tests for ==0, a boolean is 0 if it is false
    mv.visitJumpInsn(IFEQ, breakLabel);
    mv.visitVarInsn(ALOAD, iteratorIdx);
    writeIteratorNext(mv);
    operandStack.push(ClassHelper.OBJECT_TYPE);
    operandStack.storeVar(variable);
    // Generate the loop body
    loop.getLoopBlock().visit(controller.getAcg());
    mv.visitJumpInsn(GOTO, continueLabel);
    mv.visitLabel(breakLabel);
    compileStack.removeVar(iteratorIdx);
}
Also used : MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) Label(org.objectweb.asm.Label) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) BytecodeVariable(org.codehaus.groovy.classgen.asm.BytecodeVariable)

Example 100 with ArgumentListExpression

use of org.codehaus.groovy.ast.expr.ArgumentListExpression in project groovy by apache.

the class DelegateASTTransformation method addDelegateMethod.

private void addDelegateMethod(DelegateDescription delegate, List<MethodNode> ownMethods, MethodNode candidate, boolean includeDeprecated, boolean allNames) {
    if (!candidate.isPublic() || candidate.isStatic() || 0 != (candidate.getModifiers() & ACC_SYNTHETIC))
        return;
    if (!candidate.getAnnotations(DEPRECATED_TYPE).isEmpty() && !includeDeprecated)
        return;
    if (shouldSkip(candidate.getName(), delegate.excludes, delegate.includes, allNames))
        return;
    Map<String, ClassNode> genericsSpec = createGenericsSpec(delegate.owner);
    genericsSpec = addMethodGenerics(candidate, genericsSpec);
    extractSuperClassGenerics(delegate.type, candidate.getDeclaringClass(), genericsSpec);
    if ((delegate.excludeTypes != null && !delegate.excludeTypes.isEmpty()) || delegate.includeTypes != null) {
        MethodNode correctedMethodNode = correctToGenericsSpec(genericsSpec, candidate);
        boolean checkReturn = delegate.type.getMethods().contains(candidate);
        if (shouldSkipOnDescriptorUndefinedAware(checkReturn, genericsSpec, correctedMethodNode, delegate.excludeTypes, delegate.includeTypes))
            return;
    }
    // ignore methods from GroovyObject
    for (MethodNode mn : GROOVYOBJECT_TYPE.getMethods()) {
        if (mn.getTypeDescriptor().equals(candidate.getTypeDescriptor())) {
            return;
        }
    }
    // ignore methods already in owner
    for (MethodNode mn : delegate.owner.getMethods()) {
        if (mn.getTypeDescriptor().equals(candidate.getTypeDescriptor())) {
            return;
        }
    }
    // give precedence to methods of self (but not abstract or static superclass methods)
    // also allows abstract or static self methods to be selected for overriding but they are ignored later
    MethodNode existingNode = null;
    for (MethodNode mn : ownMethods) {
        if (mn.getTypeDescriptor().equals(candidate.getTypeDescriptor()) && !mn.isAbstract() && !mn.isStatic()) {
            existingNode = mn;
            break;
        }
    }
    if (existingNode == null || existingNode.getCode() == null) {
        final ArgumentListExpression args = new ArgumentListExpression();
        final Parameter[] params = candidate.getParameters();
        final Parameter[] newParams = new Parameter[params.length];
        List<String> currentMethodGenPlaceholders = genericPlaceholderNames(candidate);
        for (int i = 0; i < newParams.length; i++) {
            ClassNode newParamType = correctToGenericsSpecRecurse(genericsSpec, params[i].getType(), currentMethodGenPlaceholders);
            Parameter newParam = new Parameter(newParamType, getParamName(params, i, delegate.name));
            newParam.setInitialExpression(params[i].getInitialExpression());
            if (memberHasValue(delegate.annotation, MEMBER_PARAMETER_ANNOTATIONS, true)) {
                newParam.addAnnotations(copyAnnotatedNodeAnnotations(params[i], MY_TYPE_NAME));
            }
            newParams[i] = newParam;
            args.addExpression(varX(newParam));
        }
        boolean alsoLazy = !delegate.delegate.getAnnotations(LAZY_TYPE).isEmpty();
        // addMethod will ignore attempts to override abstract or static methods with same signature on self
        MethodCallExpression mce = callX(// use propX when lazy, because lazy is only allowed on fields/properties
        alsoLazy ? propX(varX("this"), delegate.name.substring(1)) : delegate.getOp, candidate.getName(), args);
        mce.setSourcePosition(delegate.delegate);
        ClassNode returnType = correctToGenericsSpecRecurse(genericsSpec, candidate.getReturnType(), currentMethodGenPlaceholders);
        MethodNode newMethod = delegate.owner.addMethod(candidate.getName(), candidate.getModifiers() & (~ACC_ABSTRACT) & (~ACC_NATIVE), returnType, newParams, candidate.getExceptions(), stmt(mce));
        newMethod.setGenericsTypes(candidate.getGenericsTypes());
        if (memberHasValue(delegate.annotation, MEMBER_METHOD_ANNOTATIONS, true)) {
            newMethod.addAnnotations(copyAnnotatedNodeAnnotations(candidate, MY_TYPE_NAME));
        }
    }
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) MethodNode(org.codehaus.groovy.ast.MethodNode) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) Parameter(org.codehaus.groovy.ast.Parameter)

Aggregations

ArgumentListExpression (org.codehaus.groovy.ast.expr.ArgumentListExpression)108 MethodCallExpression (org.codehaus.groovy.ast.expr.MethodCallExpression)73 VariableExpression (org.codehaus.groovy.ast.expr.VariableExpression)72 ConstantExpression (org.codehaus.groovy.ast.expr.ConstantExpression)66 Expression (org.codehaus.groovy.ast.expr.Expression)61 ClassExpression (org.codehaus.groovy.ast.expr.ClassExpression)50 BinaryExpression (org.codehaus.groovy.ast.expr.BinaryExpression)49 ClassNode (org.codehaus.groovy.ast.ClassNode)38 ExpressionStatement (org.codehaus.groovy.ast.stmt.ExpressionStatement)38 ConstructorCallExpression (org.codehaus.groovy.ast.expr.ConstructorCallExpression)36 ClosureExpression (org.codehaus.groovy.ast.expr.ClosureExpression)34 StaticMethodCallExpression (org.codehaus.groovy.ast.expr.StaticMethodCallExpression)33 TupleExpression (org.codehaus.groovy.ast.expr.TupleExpression)32 BooleanExpression (org.codehaus.groovy.ast.expr.BooleanExpression)28 DeclarationExpression (org.codehaus.groovy.ast.expr.DeclarationExpression)28 BlockStatement (org.codehaus.groovy.ast.stmt.BlockStatement)28 PropertyExpression (org.codehaus.groovy.ast.expr.PropertyExpression)27 CastExpression (org.codehaus.groovy.ast.expr.CastExpression)26 MethodNode (org.codehaus.groovy.ast.MethodNode)23 ReturnStatement (org.codehaus.groovy.ast.stmt.ReturnStatement)22