Search in sources :

Example 16 with MethodCallExpression

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

the class StatementWriter method writeForInLoop.

protected void writeForInLoop(ForStatement loop) {
    controller.getAcg().onLineNumber(loop, "visitForLoop");
    writeStatementLabel(loop);
    CompileStack compileStack = controller.getCompileStack();
    MethodVisitor mv = controller.getMethodVisitor();
    OperandStack operandStack = controller.getOperandStack();
    compileStack.pushLoop(loop.getVariableScope(), loop.getStatementLabels());
    // Declare the loop counter.
    BytecodeVariable variable = compileStack.defineVariable(loop.getVariable(), false);
    // Then get the iterator and generate the loop control
    MethodCallExpression iterator = new MethodCallExpression(loop.getCollectionExpression(), "iterator", new ArgumentListExpression());
    iterator.visit(controller.getAcg());
    operandStack.doGroovyCast(ClassHelper.Iterator_TYPE);
    final 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);
    compileStack.pop();
}
Also used : MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) Label(org.objectweb.asm.Label) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) MethodVisitor(org.objectweb.asm.MethodVisitor)

Example 17 with MethodCallExpression

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

the class ClosureWriter method createClosureClass.

protected ClassNode createClosureClass(ClosureExpression expression, int mods) {
    ClassNode classNode = controller.getClassNode();
    ClassNode outerClass = controller.getOutermostClass();
    MethodNode methodNode = controller.getMethodNode();
    String name = classNode.getName() + "$" + // add a more informative name
    controller.getContext().getNextClosureInnerName(outerClass, classNode, methodNode);
    boolean staticMethodOrInStaticClass = controller.isStaticMethod() || classNode.isStaticClass();
    Parameter[] parameters = expression.getParameters();
    if (parameters == null) {
        parameters = Parameter.EMPTY_ARRAY;
    } else if (parameters.length == 0) {
        // let's create a default 'it' parameter
        Parameter it = new Parameter(ClassHelper.OBJECT_TYPE, "it", ConstantExpression.NULL);
        parameters = new Parameter[] { it };
        Variable ref = expression.getVariableScope().getDeclaredVariable("it");
        if (ref != null)
            it.setClosureSharedVariable(ref.isClosureSharedVariable());
    }
    Parameter[] localVariableParams = getClosureSharedVariables(expression);
    removeInitialValues(localVariableParams);
    InnerClassNode answer = new InnerClassNode(classNode, name, mods, ClassHelper.CLOSURE_TYPE.getPlainNodeReference());
    answer.setEnclosingMethod(controller.getMethodNode());
    answer.setSynthetic(true);
    answer.setUsingGenerics(outerClass.isUsingGenerics());
    answer.setSourcePosition(expression);
    if (staticMethodOrInStaticClass) {
        answer.setStaticClass(true);
    }
    if (controller.isInScriptBody()) {
        answer.setScriptBody(true);
    }
    MethodNode method = answer.addMethod("doCall", ACC_PUBLIC, ClassHelper.OBJECT_TYPE, parameters, ClassNode.EMPTY_ARRAY, expression.getCode());
    method.setSourcePosition(expression);
    VariableScope varScope = expression.getVariableScope();
    if (varScope == null) {
        throw new RuntimeException("Must have a VariableScope by now! for expression: " + expression + " class: " + name);
    } else {
        method.setVariableScope(varScope.copy());
    }
    if (parameters.length > 1 || (parameters.length == 1 && parameters[0].getType() != null && parameters[0].getType() != ClassHelper.OBJECT_TYPE && !ClassHelper.OBJECT_TYPE.equals(parameters[0].getType().getComponentType()))) {
        // let's add a typesafe call method
        MethodNode call = answer.addMethod("call", ACC_PUBLIC, ClassHelper.OBJECT_TYPE, parameters, ClassNode.EMPTY_ARRAY, new ReturnStatement(new MethodCallExpression(VariableExpression.THIS_EXPRESSION, "doCall", new ArgumentListExpression(parameters))));
        call.setSourcePosition(expression);
    }
    // let's make the constructor
    BlockStatement block = new BlockStatement();
    // this block does not get a source position, because we don't
    // want this synthetic constructor to show up in corbertura reports
    VariableExpression outer = new VariableExpression("_outerInstance");
    outer.setSourcePosition(expression);
    block.getVariableScope().putReferencedLocalVariable(outer);
    VariableExpression thisObject = new VariableExpression("_thisObject");
    thisObject.setSourcePosition(expression);
    block.getVariableScope().putReferencedLocalVariable(thisObject);
    TupleExpression conArgs = new TupleExpression(outer, thisObject);
    block.addStatement(new ExpressionStatement(new ConstructorCallExpression(ClassNode.SUPER, conArgs)));
    // let's assign all the parameter fields from the outer context
    for (Parameter param : localVariableParams) {
        String paramName = param.getName();
        ClassNode type = param.getType();
        if (true) {
            VariableExpression initialValue = new VariableExpression(paramName);
            initialValue.setAccessedVariable(param);
            initialValue.setUseReferenceDirectly(true);
            ClassNode realType = type;
            type = ClassHelper.makeReference();
            param.setType(ClassHelper.makeReference());
            FieldNode paramField = answer.addField(paramName, ACC_PRIVATE | ACC_SYNTHETIC, type, initialValue);
            paramField.setOriginType(ClassHelper.getWrapper(param.getOriginType()));
            paramField.setHolder(true);
            String methodName = Verifier.capitalize(paramName);
            // let's add a getter & setter
            Expression fieldExp = new FieldExpression(paramField);
            answer.addMethod("get" + methodName, ACC_PUBLIC, realType.getPlainNodeReference(), Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, new ReturnStatement(fieldExp));
        }
    }
    Parameter[] params = new Parameter[2 + localVariableParams.length];
    params[0] = new Parameter(ClassHelper.OBJECT_TYPE, "_outerInstance");
    params[1] = new Parameter(ClassHelper.OBJECT_TYPE, "_thisObject");
    System.arraycopy(localVariableParams, 0, params, 2, localVariableParams.length);
    ASTNode sn = answer.addConstructor(ACC_PUBLIC, params, ClassNode.EMPTY_ARRAY, block);
    sn.setSourcePosition(expression);
    correctAccessedVariable(answer, expression);
    return answer;
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) InnerClassNode(org.codehaus.groovy.ast.InnerClassNode) Variable(org.codehaus.groovy.ast.Variable) FieldNode(org.codehaus.groovy.ast.FieldNode) ConstructorCallExpression(org.codehaus.groovy.ast.expr.ConstructorCallExpression) TupleExpression(org.codehaus.groovy.ast.expr.TupleExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) InnerClassNode(org.codehaus.groovy.ast.InnerClassNode) FieldExpression(org.codehaus.groovy.ast.expr.FieldExpression) MethodNode(org.codehaus.groovy.ast.MethodNode) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) Expression(org.codehaus.groovy.ast.expr.Expression) ConstructorCallExpression(org.codehaus.groovy.ast.expr.ConstructorCallExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) TupleExpression(org.codehaus.groovy.ast.expr.TupleExpression) FieldExpression(org.codehaus.groovy.ast.expr.FieldExpression) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) ReturnStatement(org.codehaus.groovy.ast.stmt.ReturnStatement) ASTNode(org.codehaus.groovy.ast.ASTNode) Parameter(org.codehaus.groovy.ast.Parameter) VariableScope(org.codehaus.groovy.ast.VariableScope)

Example 18 with MethodCallExpression

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

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 19 with MethodCallExpression

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

the class BinaryExpressionHelper method evaluateArrayAssignmentWithOperator.

protected void evaluateArrayAssignmentWithOperator(String method, BinaryExpression expression, BinaryExpression leftBinExpr) {
    CompileStack compileStack = getController().getCompileStack();
    AsmClassGenerator acg = getController().getAcg();
    OperandStack os = getController().getOperandStack();
    // e.g. x[a] += b
    // to avoid loading x and a twice we transform the expression to use
    // ExpressionAsVariableSlot
    // -> subscript=a, receiver=x, receiver[subscript]+b, =, receiver[subscript]
    // -> subscript=a, receiver=x, receiver#getAt(subscript)#plus(b), =, receiver#putAt(subscript)
    // -> subscript=a, receiver=x, receiver#putAt(subscript, receiver#getAt(subscript)#plus(b))
    // the result of x[a] += b is x[a]+b, thus:
    // -> subscript=a, receiver=x, receiver#putAt(subscript, ret=receiver#getAt(subscript)#plus(b)), ret
    ExpressionAsVariableSlot subscript = new ExpressionAsVariableSlot(controller, leftBinExpr.getRightExpression(), "subscript");
    ExpressionAsVariableSlot receiver = new ExpressionAsVariableSlot(controller, leftBinExpr.getLeftExpression(), "receiver");
    MethodCallExpression getAt = new MethodCallExpression(receiver, "getAt", new ArgumentListExpression(subscript));
    MethodCallExpression operation = new MethodCallExpression(getAt, method, expression.getRightExpression());
    ExpressionAsVariableSlot ret = new ExpressionAsVariableSlot(controller, operation, "ret");
    MethodCallExpression putAt = new MethodCallExpression(receiver, "putAt", new ArgumentListExpression(subscript, ret));
    putAt.visit(acg);
    os.pop();
    os.load(ret.getType(), ret.getIndex());
    compileStack.removeVar(ret.getIndex());
    compileStack.removeVar(subscript.getIndex());
    compileStack.removeVar(receiver.getIndex());
}
Also used : MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) AsmClassGenerator(org.codehaus.groovy.classgen.AsmClassGenerator)

Example 20 with MethodCallExpression

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

the class StaticImportVisitor method transformPropertyExpression.

protected Expression transformPropertyExpression(PropertyExpression pe) {
    if (currentMethod != null && currentMethod.isStatic() && pe.getObjectExpression() instanceof VariableExpression && ((VariableExpression) pe.getObjectExpression()).isSuperExpression()) {
        PropertyExpression pexp = new PropertyExpression(new ClassExpression(currentClass.getSuperClass()), transform(pe.getProperty()));
        pexp.setSourcePosition(pe);
        return pexp;
    }
    boolean oldInPropertyExpression = inPropertyExpression;
    Expression oldFoundArgs = foundArgs;
    Expression oldFoundConstant = foundConstant;
    inPropertyExpression = true;
    foundArgs = null;
    foundConstant = null;
    Expression objectExpression = transform(pe.getObjectExpression());
    boolean candidate = false;
    if (objectExpression instanceof MethodCallExpression) {
        candidate = ((MethodCallExpression) objectExpression).isImplicitThis();
    }
    if (foundArgs != null && foundConstant != null && candidate) {
        Expression result = findStaticMethodImportFromModule(foundConstant, foundArgs);
        if (result != null) {
            objectExpression = result;
            objectExpression.setSourcePosition(pe);
        }
    }
    inPropertyExpression = oldInPropertyExpression;
    foundArgs = oldFoundArgs;
    foundConstant = oldFoundConstant;
    pe.setObjectExpression(objectExpression);
    return pe;
}
Also used : StaticMethodCallExpression(org.codehaus.groovy.ast.expr.StaticMethodCallExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) ListExpression(org.codehaus.groovy.ast.expr.ListExpression) PropertyExpression(org.codehaus.groovy.ast.expr.PropertyExpression) StaticMethodCallExpression(org.codehaus.groovy.ast.expr.StaticMethodCallExpression) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) NamedArgumentListExpression(org.codehaus.groovy.ast.expr.NamedArgumentListExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) EmptyExpression(org.codehaus.groovy.ast.expr.EmptyExpression) Expression(org.codehaus.groovy.ast.expr.Expression) ConstructorCallExpression(org.codehaus.groovy.ast.expr.ConstructorCallExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) AnnotationConstantExpression(org.codehaus.groovy.ast.expr.AnnotationConstantExpression) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) TupleExpression(org.codehaus.groovy.ast.expr.TupleExpression) BinaryExpression(org.codehaus.groovy.ast.expr.BinaryExpression) MapEntryExpression(org.codehaus.groovy.ast.expr.MapEntryExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) PropertyExpression(org.codehaus.groovy.ast.expr.PropertyExpression) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression)

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