Search in sources :

Example 36 with BinaryExpression

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

the class BinaryExpressionMultiTypeDispatcher method doAssignmentToArray.

private boolean doAssignmentToArray(BinaryExpression binExp) {
    if (!isAssignmentToArray(binExp))
        return false;
    // we need to handle only assignment to arrays combined with an operation
    // special here. e.g x[a] += b
    int operation = removeAssignment(binExp.getOperation().getType());
    ClassNode current = getController().getClassNode();
    Expression leftExp = binExp.getLeftExpression();
    ClassNode leftType = getController().getTypeChooser().resolveType(leftExp, current);
    Expression rightExp = binExp.getRightExpression();
    ClassNode rightType = getController().getTypeChooser().resolveType(rightExp, current);
    int operationType = getOperandType(leftType);
    BinaryExpressionWriter bew = binExpWriter[operationType];
    boolean simulationSuccess = bew.arrayGet(LEFT_SQUARE_BRACKET, true);
    simulationSuccess = simulationSuccess && bew.write(operation, true);
    simulationSuccess = simulationSuccess && bew.arraySet(true);
    if (!simulationSuccess)
        return false;
    AsmClassGenerator acg = getController().getAcg();
    OperandStack operandStack = getController().getOperandStack();
    CompileStack compileStack = getController().getCompileStack();
    // for x[a] += b we have the structure:
    //   x = left(left(binExp))), b = right(binExp), a = right(left(binExp)))
    // for array set we need these values on stack: array, index, right 
    // for array get we need these values on stack: array, index
    // to eval the expression we need x[a] = x[a]+b
    // -> arraySet(x,a, x[a]+b) 
    // -> arraySet(x,a, arrayGet(x,a,b))
    // --> x,a, x,a, b as operands
    // --> load x, load a, DUP2, call arrayGet, load b, call operation,call arraySet
    // since we cannot DUP2 here easily we will save the subscript and DUP x
    // --> sub=a, load x, DUP, load sub, call arrayGet, load b, call operation, load sub, call arraySet
    BinaryExpression arrayWithSubscript = (BinaryExpression) leftExp;
    Expression subscript = arrayWithSubscript.getRightExpression();
    // load array index: sub=a [load x, DUP, load sub, call arrayGet, load b, call operation, load sub, call arraySet]
    subscript.visit(acg);
    operandStack.doGroovyCast(int_TYPE);
    int subscriptValueId = compileStack.defineTemporaryVariable("$sub", ClassHelper.int_TYPE, true);
    // load array: load x and DUP [load sub, call arrayGet, load b, call operation, load sub, call arraySet] 
    arrayWithSubscript.getLeftExpression().visit(acg);
    operandStack.doGroovyCast(leftType.makeArray());
    operandStack.dup();
    // array get: load sub, call arrayGet [load b, call operation, load sub, call arraySet]
    operandStack.load(ClassHelper.int_TYPE, subscriptValueId);
    bew.arrayGet(LEFT_SQUARE_BRACKET, false);
    operandStack.replace(leftType, 2);
    // complete rhs: load b, call operation [load sub, call arraySet]
    binExp.getRightExpression().visit(acg);
    if (!(bew instanceof BinaryObjectExpressionHelper)) {
        // in primopts we convert to the left type for supported binary operations
        operandStack.doGroovyCast(leftType);
    }
    bew.write(operation, false);
    // let us save that value for the return
    operandStack.dup();
    int resultValueId = compileStack.defineTemporaryVariable("$result", rightType, true);
    // array set: load sub, call arraySet []
    operandStack.load(ClassHelper.int_TYPE, subscriptValueId);
    operandStack.swap();
    bew.arraySet(false);
    // 3 operands, the array, the index and the value!
    operandStack.remove(3);
    // load return value
    operandStack.load(rightType, resultValueId);
    // cleanup
    compileStack.removeVar(resultValueId);
    compileStack.removeVar(subscriptValueId);
    return true;
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) BinaryExpression(org.codehaus.groovy.ast.expr.BinaryExpression) PropertyExpression(org.codehaus.groovy.ast.expr.PropertyExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) BinaryExpression(org.codehaus.groovy.ast.expr.BinaryExpression) Expression(org.codehaus.groovy.ast.expr.Expression) AsmClassGenerator(org.codehaus.groovy.classgen.AsmClassGenerator)

Example 37 with BinaryExpression

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

the class FinalVariableAnalyzer method visitBinaryExpression.

@Override
public void visitBinaryExpression(final BinaryExpression expression) {
    boolean assignment = StaticTypeCheckingSupport.isAssignment(expression.getOperation().getType());
    boolean isDeclaration = expression instanceof DeclarationExpression;
    Expression leftExpression = expression.getLeftExpression();
    Expression rightExpression = expression.getRightExpression();
    if (isDeclaration && leftExpression instanceof VariableExpression) {
        VariableExpression var = (VariableExpression) leftExpression;
        if (Modifier.isFinal(var.getModifiers())) {
            declaredFinalVariables.add(var);
        }
    }
    leftExpression.visit(this);
    inAssignment = assignment;
    rightExpression.visit(this);
    inAssignment = false;
    if (assignment) {
        if (leftExpression instanceof Variable) {
            boolean uninitialized = isDeclaration && rightExpression == EmptyExpression.INSTANCE;
            recordAssignment((Variable) leftExpression, isDeclaration, uninitialized, false, expression);
        } else if (leftExpression instanceof TupleExpression) {
            TupleExpression te = (TupleExpression) leftExpression;
            for (Expression next : te.getExpressions()) {
                if (next instanceof Variable) {
                    recordAssignment((Variable) next, isDeclaration, false, false, next);
                }
            }
        }
    }
}
Also used : Variable(org.codehaus.groovy.ast.Variable) PrefixExpression(org.codehaus.groovy.ast.expr.PrefixExpression) PostfixExpression(org.codehaus.groovy.ast.expr.PostfixExpression) EmptyExpression(org.codehaus.groovy.ast.expr.EmptyExpression) Expression(org.codehaus.groovy.ast.expr.Expression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) DeclarationExpression(org.codehaus.groovy.ast.expr.DeclarationExpression) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression) TupleExpression(org.codehaus.groovy.ast.expr.TupleExpression) BinaryExpression(org.codehaus.groovy.ast.expr.BinaryExpression) DeclarationExpression(org.codehaus.groovy.ast.expr.DeclarationExpression) TupleExpression(org.codehaus.groovy.ast.expr.TupleExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression)

Example 38 with BinaryExpression

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

the class IfElseTest method testLoop.

public void testLoop() throws Exception {
    ClassNode classNode = new ClassNode("Foo", ACC_PUBLIC, ClassHelper.OBJECT_TYPE);
    classNode.addConstructor(new ConstructorNode(ACC_PUBLIC, null));
    classNode.addProperty(new PropertyNode("bar", ACC_PUBLIC, ClassHelper.STRING_TYPE, classNode, null, null, null));
    classNode.addProperty(new PropertyNode("result", ACC_PUBLIC, ClassHelper.STRING_TYPE, classNode, null, null, null));
    BooleanExpression expression = new BooleanExpression(new BinaryExpression(new FieldExpression(new FieldNode("bar", ACC_PRIVATE, ClassHelper.STRING_TYPE, classNode, ConstantExpression.NULL)), Token.newSymbol("==", 0, 0), new ConstantExpression("abc")));
    Statement trueStatement = new ExpressionStatement(new BinaryExpression(new FieldExpression(new FieldNode("result", ACC_PRIVATE, ClassHelper.STRING_TYPE, classNode, ConstantExpression.NULL)), Token.newSymbol("=", 0, 0), new ConstantExpression("worked")));
    Statement falseStatement = createPrintlnStatement(new ConstantExpression("false"));
    IfStatement statement = new IfStatement(expression, trueStatement, falseStatement);
    classNode.addMethod(new MethodNode("ifDemo", ACC_PUBLIC, ClassHelper.VOID_TYPE, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, statement));
    Class fooClass = loadClass(classNode);
    assertTrue("Loaded a new class", fooClass != null);
    Object bean = fooClass.newInstance();
    assertTrue("Managed to create bean", bean != null);
    assertSetProperty(bean, "bar", "abc");
    System.out.println("################ Now about to invoke method");
    Object[] array = {};
    InvokerHelper.invokeMethod(bean, "ifDemo", array);
    System.out.println("################ Done");
    assertGetProperty(bean, "result", "worked");
}
Also used : Statement(org.codehaus.groovy.ast.stmt.Statement) IfStatement(org.codehaus.groovy.ast.stmt.IfStatement) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) FieldExpression(org.codehaus.groovy.ast.expr.FieldExpression) IfStatement(org.codehaus.groovy.ast.stmt.IfStatement) BooleanExpression(org.codehaus.groovy.ast.expr.BooleanExpression) BinaryExpression(org.codehaus.groovy.ast.expr.BinaryExpression) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement)

Example 39 with BinaryExpression

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

the class StaticImportVisitor method transformBinaryExpression.

protected Expression transformBinaryExpression(BinaryExpression be) {
    int type = be.getOperation().getType();
    boolean oldInLeftExpression;
    Expression right = transform(be.getRightExpression());
    be.setRightExpression(right);
    Expression left;
    if (type == Types.EQUAL && be.getLeftExpression() instanceof VariableExpression) {
        oldInLeftExpression = inLeftExpression;
        inLeftExpression = true;
        left = transform(be.getLeftExpression());
        inLeftExpression = oldInLeftExpression;
        if (left instanceof StaticMethodCallExpression) {
            StaticMethodCallExpression smce = (StaticMethodCallExpression) left;
            StaticMethodCallExpression result = new StaticMethodCallExpression(smce.getOwnerType(), smce.getMethod(), right);
            setSourcePosition(result, be);
            return result;
        }
    } else {
        left = transform(be.getLeftExpression());
    }
    be.setLeftExpression(left);
    return be;
}
Also used : 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) StaticMethodCallExpression(org.codehaus.groovy.ast.expr.StaticMethodCallExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression)

Example 40 with BinaryExpression

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

the class TraitReceiverTransformer method transformBinaryExpression.

private Expression transformBinaryExpression(final BinaryExpression exp, final ClassNode weavedType) {
    Expression leftExpression = exp.getLeftExpression();
    Expression rightExpression = exp.getRightExpression();
    Token operation = exp.getOperation();
    if (operation.getText().equals("=")) {
        String leftFieldName = null;
        // it's an assignment
        if (leftExpression instanceof VariableExpression && ((VariableExpression) leftExpression).getAccessedVariable() instanceof FieldNode) {
            leftFieldName = ((VariableExpression) leftExpression).getAccessedVariable().getName();
        } else if (leftExpression instanceof FieldExpression) {
            leftFieldName = ((FieldExpression) leftExpression).getFieldName();
        } else if (leftExpression instanceof PropertyExpression && (((PropertyExpression) leftExpression).isImplicitThis() || "this".equals(((PropertyExpression) leftExpression).getObjectExpression().getText()))) {
            leftFieldName = ((PropertyExpression) leftExpression).getPropertyAsString();
            FieldNode fn = tryGetFieldNode(weavedType, leftFieldName);
            if (fieldHelper == null || fn == null && !fieldHelper.hasPossibleMethod(Traits.helperSetterName(new FieldNode(leftFieldName, 0, ClassHelper.OBJECT_TYPE, weavedType, null)), rightExpression)) {
                return createAssignmentToField(rightExpression, operation, leftFieldName);
            }
        }
        if (leftFieldName != null) {
            FieldNode fn = weavedType.getDeclaredField(leftFieldName);
            FieldNode staticField = tryGetFieldNode(weavedType, leftFieldName);
            if (fn == null) {
                fn = new FieldNode(leftFieldName, 0, ClassHelper.OBJECT_TYPE, weavedType, null);
            }
            Expression receiver = createFieldHelperReceiver();
            boolean isStatic = staticField != null && staticField.isStatic();
            if (fn.isStatic()) {
                // DO NOT USE isStatic variable here!
                receiver = new PropertyExpression(receiver, "class");
            }
            String method = Traits.helperSetterName(fn);
            MethodCallExpression mce = new MethodCallExpression(receiver, method, new ArgumentListExpression(super.transform(rightExpression)));
            mce.setSourcePosition(exp);
            mce.setImplicitThis(false);
            markDynamicCall(mce, staticField, isStatic);
            return mce;
        }
    }
    Expression leftTransform = transform(leftExpression);
    Expression rightTransform = transform(rightExpression);
    Expression ret = exp instanceof DeclarationExpression ? new DeclarationExpression(leftTransform, operation, rightTransform) : new BinaryExpression(leftTransform, operation, rightTransform);
    ret.setSourcePosition(exp);
    ret.copyNodeMetaData(exp);
    return ret;
}
Also used : FieldNode(org.codehaus.groovy.ast.FieldNode) StaticMethodCallExpression(org.codehaus.groovy.ast.expr.StaticMethodCallExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) BinaryExpression(org.codehaus.groovy.ast.expr.BinaryExpression) BooleanExpression(org.codehaus.groovy.ast.expr.BooleanExpression) PropertyExpression(org.codehaus.groovy.ast.expr.PropertyExpression) StaticMethodCallExpression(org.codehaus.groovy.ast.expr.StaticMethodCallExpression) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) Expression(org.codehaus.groovy.ast.expr.Expression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) DeclarationExpression(org.codehaus.groovy.ast.expr.DeclarationExpression) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) BinaryExpression(org.codehaus.groovy.ast.expr.BinaryExpression) FieldExpression(org.codehaus.groovy.ast.expr.FieldExpression) TernaryExpression(org.codehaus.groovy.ast.expr.TernaryExpression) CastExpression(org.codehaus.groovy.ast.expr.CastExpression) DeclarationExpression(org.codehaus.groovy.ast.expr.DeclarationExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) Token(org.codehaus.groovy.syntax.Token) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) PropertyExpression(org.codehaus.groovy.ast.expr.PropertyExpression) FieldExpression(org.codehaus.groovy.ast.expr.FieldExpression)

Aggregations

BinaryExpression (org.codehaus.groovy.ast.expr.BinaryExpression)94 VariableExpression (org.codehaus.groovy.ast.expr.VariableExpression)83 Expression (org.codehaus.groovy.ast.expr.Expression)71 ConstantExpression (org.codehaus.groovy.ast.expr.ConstantExpression)57 MethodCallExpression (org.codehaus.groovy.ast.expr.MethodCallExpression)51 ArgumentListExpression (org.codehaus.groovy.ast.expr.ArgumentListExpression)49 PropertyExpression (org.codehaus.groovy.ast.expr.PropertyExpression)48 ClassExpression (org.codehaus.groovy.ast.expr.ClassExpression)39 TupleExpression (org.codehaus.groovy.ast.expr.TupleExpression)35 BooleanExpression (org.codehaus.groovy.ast.expr.BooleanExpression)33 ClassNode (org.codehaus.groovy.ast.ClassNode)31 TernaryExpression (org.codehaus.groovy.ast.expr.TernaryExpression)29 EmptyExpression (org.codehaus.groovy.ast.expr.EmptyExpression)28 FieldExpression (org.codehaus.groovy.ast.expr.FieldExpression)28 ListExpression (org.codehaus.groovy.ast.expr.ListExpression)26 DeclarationExpression (org.codehaus.groovy.ast.expr.DeclarationExpression)24 CastExpression (org.codehaus.groovy.ast.expr.CastExpression)21 ExpressionStatement (org.codehaus.groovy.ast.stmt.ExpressionStatement)21 ArrayExpression (org.codehaus.groovy.ast.expr.ArrayExpression)20 ClosureExpression (org.codehaus.groovy.ast.expr.ClosureExpression)20