Search in sources :

Example 31 with MethodCallExpression

use of org.codehaus.groovy.ast.expr.MethodCallExpression in project groovy-core by groovy.

the class BinaryExpressionHelper method evaluateEqual.

public void evaluateEqual(BinaryExpression expression, boolean defineVariable) {
    AsmClassGenerator acg = controller.getAcg();
    CompileStack compileStack = controller.getCompileStack();
    OperandStack operandStack = controller.getOperandStack();
    Expression rightExpression = expression.getRightExpression();
    Expression leftExpression = expression.getLeftExpression();
    ClassNode lhsType = controller.getTypeChooser().resolveType(leftExpression, controller.getClassNode());
    if (defineVariable && rightExpression instanceof EmptyExpression && !(leftExpression instanceof TupleExpression)) {
        VariableExpression ve = (VariableExpression) leftExpression;
        BytecodeVariable var = compileStack.defineVariable(ve, controller.getTypeChooser().resolveType(ve, controller.getClassNode()), false);
        operandStack.loadOrStoreVariable(var, false);
        return;
    }
    // let's evaluate the RHS and store the result
    ClassNode rhsType;
    if (rightExpression instanceof ListExpression && lhsType.isArray()) {
        ListExpression list = (ListExpression) rightExpression;
        ArrayExpression array = new ArrayExpression(lhsType.getComponentType(), list.getExpressions());
        array.setSourcePosition(list);
        array.visit(acg);
    } else if (rightExpression instanceof EmptyExpression) {
        rhsType = leftExpression.getType();
        loadInitValue(rhsType);
    } else {
        rightExpression.visit(acg);
    }
    rhsType = operandStack.getTopOperand();
    boolean directAssignment = defineVariable && !(leftExpression instanceof TupleExpression);
    int rhsValueId;
    if (directAssignment) {
        VariableExpression var = (VariableExpression) leftExpression;
        if (var.isClosureSharedVariable() && ClassHelper.isPrimitiveType(rhsType)) {
            // GROOVY-5570: if a closure shared variable is a primitive type, it must be boxed
            rhsType = ClassHelper.getWrapper(rhsType);
            operandStack.box();
        }
        // form as it is closure shared
        if (var.isClosureSharedVariable() && ClassHelper.isPrimitiveType(var.getOriginType()) && isNull(rightExpression)) {
            operandStack.doGroovyCast(var.getOriginType());
            // these two are never reached in bytecode and only there 
            // to avoid verifyerrors and compiler infrastructure hazzle
            operandStack.box();
            operandStack.doGroovyCast(lhsType);
        }
        // normal type transformation 
        if (!ClassHelper.isPrimitiveType(lhsType) && isNull(rightExpression)) {
            operandStack.replace(lhsType);
        } else {
            operandStack.doGroovyCast(lhsType);
        }
        rhsType = lhsType;
        rhsValueId = compileStack.defineVariable(var, lhsType, true).getIndex();
    } else {
        rhsValueId = compileStack.defineTemporaryVariable("$rhs", rhsType, true);
    }
    //TODO: if rhs is VariableSlotLoader already, then skip crating a new one
    BytecodeExpression rhsValueLoader = new VariableSlotLoader(rhsType, rhsValueId, operandStack);
    // assignment for subscript
    if (leftExpression instanceof BinaryExpression) {
        BinaryExpression leftBinExpr = (BinaryExpression) leftExpression;
        if (leftBinExpr.getOperation().getType() == Types.LEFT_SQUARE_BRACKET) {
            assignToArray(expression, leftBinExpr.getLeftExpression(), leftBinExpr.getRightExpression(), rhsValueLoader);
        }
        compileStack.removeVar(rhsValueId);
        return;
    }
    compileStack.pushLHS(true);
    // multiple declaration
    if (leftExpression instanceof TupleExpression) {
        TupleExpression tuple = (TupleExpression) leftExpression;
        int i = 0;
        for (Expression e : tuple.getExpressions()) {
            VariableExpression var = (VariableExpression) e;
            MethodCallExpression call = new MethodCallExpression(rhsValueLoader, "getAt", new ArgumentListExpression(new ConstantExpression(i)));
            call.visit(acg);
            i++;
            if (defineVariable) {
                operandStack.doGroovyCast(var);
                compileStack.defineVariable(var, true);
                operandStack.remove(1);
            } else {
                acg.visitVariableExpression(var);
            }
        }
    } else // single declaration
    if (defineVariable) {
        rhsValueLoader.visit(acg);
        operandStack.remove(1);
        compileStack.popLHS();
        return;
    } else // normal assignment
    {
        int mark = operandStack.getStackLength();
        // to leave a copy of the rightExpression value on the stack after the assignment.
        rhsValueLoader.visit(acg);
        TypeChooser typeChooser = controller.getTypeChooser();
        ClassNode targetType = typeChooser.resolveType(leftExpression, controller.getClassNode());
        operandStack.doGroovyCast(targetType);
        leftExpression.visit(acg);
        operandStack.remove(operandStack.getStackLength() - mark);
    }
    compileStack.popLHS();
    // return value of assignment
    rhsValueLoader.visit(acg);
    compileStack.removeVar(rhsValueId);
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) ListExpression(org.codehaus.groovy.ast.expr.ListExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) TupleExpression(org.codehaus.groovy.ast.expr.TupleExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) AsmClassGenerator(org.codehaus.groovy.classgen.AsmClassGenerator) EmptyExpression(org.codehaus.groovy.ast.expr.EmptyExpression) BinaryExpression(org.codehaus.groovy.ast.expr.BinaryExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) ListExpression(org.codehaus.groovy.ast.expr.ListExpression) PropertyExpression(org.codehaus.groovy.ast.expr.PropertyExpression) ElvisOperatorExpression(org.codehaus.groovy.ast.expr.ElvisOperatorExpression) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) PrefixExpression(org.codehaus.groovy.ast.expr.PrefixExpression) PostfixExpression(org.codehaus.groovy.ast.expr.PostfixExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) BytecodeExpression(org.codehaus.groovy.classgen.BytecodeExpression) EmptyExpression(org.codehaus.groovy.ast.expr.EmptyExpression) Expression(org.codehaus.groovy.ast.expr.Expression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) ArrayExpression(org.codehaus.groovy.ast.expr.ArrayExpression) 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) FieldExpression(org.codehaus.groovy.ast.expr.FieldExpression) TernaryExpression(org.codehaus.groovy.ast.expr.TernaryExpression) ArrayExpression(org.codehaus.groovy.ast.expr.ArrayExpression) BytecodeExpression(org.codehaus.groovy.classgen.BytecodeExpression)

Example 32 with MethodCallExpression

use of org.codehaus.groovy.ast.expr.MethodCallExpression in project grails-core by grails.

the class DelegateAsyncTransformation method applyDelegateAsyncTransform.

private void applyDelegateAsyncTransform(ClassNode classNode, ClassNode targetApi, String fieldName) {
    List<MethodNode> methods = targetApi.getAllDeclaredMethods();
    ClassNode promisesClass = ClassHelper.make(Promises.class).getPlainNodeReference();
    MethodNode createPromiseMethodTargetWithDecorators = promisesClass.getDeclaredMethod("createPromise", new Parameter[] { new Parameter(new ClassNode(Closure.class), "c"), new Parameter(new ClassNode(List.class), "c") });
    DelegateAsyncTransactionalMethodTransformer delegateAsyncTransactionalMethodTransformer = lookupAsyncTransactionalMethodTransformer();
    for (MethodNode m : methods) {
        if (isCandidateMethod(m)) {
            MethodNode existingMethod = classNode.getMethod(m.getName(), m.getParameters());
            if (existingMethod == null) {
                ClassNode promiseNode = ClassHelper.make(Promise.class).getPlainNodeReference();
                ClassNode originalReturnType = m.getReturnType();
                if (!originalReturnType.getNameWithoutPackage().equals(VOID)) {
                    ClassNode returnType;
                    if (ClassHelper.isPrimitiveType(originalReturnType.redirect())) {
                        returnType = ClassHelper.getWrapper(originalReturnType.redirect());
                    } else {
                        returnType = alignReturnType(classNode, originalReturnType);
                    }
                    if (!OBJECT_CLASS_NODE.equals(returnType)) {
                        promiseNode.setGenericsTypes(new GenericsType[] { new GenericsType(returnType) });
                    }
                }
                final BlockStatement methodBody = new BlockStatement();
                final BlockStatement promiseBody = new BlockStatement();
                final ClosureExpression closureExpression = new ClosureExpression(new Parameter[0], promiseBody);
                VariableScope variableScope = new VariableScope();
                closureExpression.setVariableScope(variableScope);
                VariableExpression thisObject = new VariableExpression("this");
                ClassNode delegateAsyncUtilsClassNode = new ClassNode(DelegateAsyncUtils.class);
                MethodNode getPromiseDecoratorsMethodNode = delegateAsyncUtilsClassNode.getDeclaredMethods("getPromiseDecorators").get(0);
                ListExpression promiseDecorators = new ListExpression();
                ArgumentListExpression getPromiseDecoratorsArguments = new ArgumentListExpression(thisObject, promiseDecorators);
                delegateAsyncTransactionalMethodTransformer.transformTransactionalMethod(classNode, targetApi, m, promiseDecorators);
                MethodCallExpression getDecoratorsMethodCall = new MethodCallExpression(new ClassExpression(delegateAsyncUtilsClassNode), "getPromiseDecorators", getPromiseDecoratorsArguments);
                getDecoratorsMethodCall.setMethodTarget(getPromiseDecoratorsMethodNode);
                MethodCallExpression createPromiseWithDecorators = new MethodCallExpression(new ClassExpression(promisesClass), "createPromise", new ArgumentListExpression(closureExpression, getDecoratorsMethodCall));
                if (createPromiseMethodTargetWithDecorators != null) {
                    createPromiseWithDecorators.setMethodTarget(createPromiseMethodTargetWithDecorators);
                }
                methodBody.addStatement(new ExpressionStatement(createPromiseWithDecorators));
                final ArgumentListExpression arguments = new ArgumentListExpression();
                Parameter[] parameters = copyParameters(StaticTypeCheckingSupport.parameterizeArguments(classNode, m));
                for (Parameter p : parameters) {
                    p.setClosureSharedVariable(true);
                    variableScope.putReferencedLocalVariable(p);
                    VariableExpression ve = new VariableExpression(p);
                    ve.setClosureSharedVariable(true);
                    arguments.addExpression(ve);
                }
                MethodCallExpression delegateMethodCall = new MethodCallExpression(new VariableExpression(fieldName), m.getName(), arguments);
                promiseBody.addStatement(new ExpressionStatement(delegateMethodCall));
                MethodNode newMethodNode = new MethodNode(m.getName(), Modifier.PUBLIC, promiseNode, parameters, null, methodBody);
                classNode.addMethod(newMethodNode);
            }
        }
    }
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) Promises(grails.async.Promises) ListExpression(org.codehaus.groovy.ast.expr.ListExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) Promise(grails.async.Promise) MethodNode(org.codehaus.groovy.ast.MethodNode) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) GenericsType(org.codehaus.groovy.ast.GenericsType) Parameter(org.codehaus.groovy.ast.Parameter) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression) VariableScope(org.codehaus.groovy.ast.VariableScope)

Example 33 with MethodCallExpression

use of org.codehaus.groovy.ast.expr.MethodCallExpression in project groovy-core by groovy.

the class StaticPropertyAccessHelper method transformToSetterCall.

public static Expression transformToSetterCall(Expression receiver, MethodNode setterMethod, final Expression arguments, boolean implicitThis, boolean safe, boolean spreadSafe, boolean requiresReturnValue, Expression location) {
    if (requiresReturnValue) {
        TemporaryVariableExpression tmp = new TemporaryVariableExpression(arguments);
        PoppingMethodCallExpression call = new PoppingMethodCallExpression(receiver, setterMethod, tmp);
        call.setImplicitThis(implicitThis);
        call.setSafe(safe);
        call.setSpreadSafe(spreadSafe);
        call.setSourcePosition(location);
        PoppingListOfExpressionsExpression result = new PoppingListOfExpressionsExpression(tmp, call);
        result.setSourcePosition(location);
        return result;
    } else {
        MethodCallExpression call = new MethodCallExpression(receiver, setterMethod.getName(), arguments);
        call.setImplicitThis(implicitThis);
        call.setSafe(safe);
        call.setSpreadSafe(spreadSafe);
        call.setMethodTarget(setterMethod);
        call.setSourcePosition(location);
        return call;
    }
}
Also used : TemporaryVariableExpression(org.codehaus.groovy.transform.sc.TemporaryVariableExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression)

Example 34 with MethodCallExpression

use of org.codehaus.groovy.ast.expr.MethodCallExpression in project groovy-core by groovy.

the class StaticTypesClosureWriter method createDirectCallMethod.

private 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 35 with MethodCallExpression

use of org.codehaus.groovy.ast.expr.MethodCallExpression in project groovy-core by groovy.

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);
}
Also used : MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) Label(org.objectweb.asm.Label) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression)

Aggregations

MethodCallExpression (org.codehaus.groovy.ast.expr.MethodCallExpression)131 VariableExpression (org.codehaus.groovy.ast.expr.VariableExpression)89 ArgumentListExpression (org.codehaus.groovy.ast.expr.ArgumentListExpression)81 Expression (org.codehaus.groovy.ast.expr.Expression)77 ConstantExpression (org.codehaus.groovy.ast.expr.ConstantExpression)73 ClassExpression (org.codehaus.groovy.ast.expr.ClassExpression)59 BinaryExpression (org.codehaus.groovy.ast.expr.BinaryExpression)58 ClosureExpression (org.codehaus.groovy.ast.expr.ClosureExpression)51 ClassNode (org.codehaus.groovy.ast.ClassNode)43 TupleExpression (org.codehaus.groovy.ast.expr.TupleExpression)42 StaticMethodCallExpression (org.codehaus.groovy.ast.expr.StaticMethodCallExpression)40 MethodNode (org.codehaus.groovy.ast.MethodNode)36 PropertyExpression (org.codehaus.groovy.ast.expr.PropertyExpression)36 BlockStatement (org.codehaus.groovy.ast.stmt.BlockStatement)36 ConstructorCallExpression (org.codehaus.groovy.ast.expr.ConstructorCallExpression)35 ExpressionStatement (org.codehaus.groovy.ast.stmt.ExpressionStatement)35 DeclarationExpression (org.codehaus.groovy.ast.expr.DeclarationExpression)34 BooleanExpression (org.codehaus.groovy.ast.expr.BooleanExpression)31 FieldNode (org.codehaus.groovy.ast.FieldNode)26 Parameter (org.codehaus.groovy.ast.Parameter)23