Search in sources :

Example 91 with ClassExpression

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

the class BinaryExpressionTransformer method transformBinaryExpression.

Expression transformBinaryExpression(final BinaryExpression bin) {
    if (bin instanceof DeclarationExpression) {
        Expression optimized = transformDeclarationExpression(bin);
        if (optimized != null) {
            return optimized;
        }
    }
    Object[] list = bin.getNodeMetaData(BINARY_EXP_TARGET);
    Token operation = bin.getOperation();
    int operationType = operation.getType();
    Expression rightExpression = bin.getRightExpression();
    Expression leftExpression = bin.getLeftExpression();
    if (bin instanceof DeclarationExpression && leftExpression instanceof VariableExpression) {
        ClassNode declarationType = ((VariableExpression) leftExpression).getOriginType();
        if (rightExpression instanceof ConstantExpression) {
            ClassNode unwrapper = ClassHelper.getUnwrapper(declarationType);
            ClassNode wrapper = ClassHelper.getWrapper(declarationType);
            if (!rightExpression.getType().equals(declarationType) && wrapper.isDerivedFrom(ClassHelper.Number_TYPE) && WideningCategories.isDoubleCategory(unwrapper)) {
                ConstantExpression constant = (ConstantExpression) rightExpression;
                if (constant.getValue() != null) {
                    return optimizeConstantInitialization(bin, operation, constant, leftExpression, declarationType);
                }
            }
        }
    }
    if (operationType == Types.EQUAL && leftExpression instanceof PropertyExpression) {
        MethodNode directMCT = leftExpression.getNodeMetaData(StaticTypesMarker.DIRECT_METHOD_CALL_TARGET);
        if (directMCT != null) {
            return transformPropertyAssignmentToSetterCall((PropertyExpression) leftExpression, rightExpression, directMCT);
        }
    }
    if (operationType == Types.COMPARE_EQUAL || operationType == Types.COMPARE_NOT_EQUAL) {
        // let's check if one of the operands is the null constant
        CompareToNullExpression compareToNullExpression = null;
        if (isNullConstant(leftExpression)) {
            compareToNullExpression = new CompareToNullExpression(staticCompilationTransformer.transform(rightExpression), operationType == Types.COMPARE_EQUAL);
        } else if (isNullConstant(rightExpression)) {
            compareToNullExpression = new CompareToNullExpression(staticCompilationTransformer.transform(leftExpression), operationType == Types.COMPARE_EQUAL);
        }
        if (compareToNullExpression != null) {
            compareToNullExpression.setSourcePosition(bin);
            return compareToNullExpression;
        }
    } else if (operationType == Types.KEYWORD_IN) {
        return convertInOperatorToTernary(bin, rightExpression, leftExpression);
    }
    if (list != null) {
        if (operationType == Types.COMPARE_TO) {
            StaticTypesTypeChooser typeChooser = staticCompilationTransformer.getTypeChooser();
            ClassNode classNode = staticCompilationTransformer.getClassNode();
            ClassNode leftType = typeChooser.resolveType(leftExpression, classNode);
            if (leftType.implementsInterface(ClassHelper.COMPARABLE_TYPE)) {
                ClassNode rightType = typeChooser.resolveType(rightExpression, classNode);
                if (rightType.implementsInterface(ClassHelper.COMPARABLE_TYPE)) {
                    Expression left = staticCompilationTransformer.transform(leftExpression);
                    Expression right = staticCompilationTransformer.transform(rightExpression);
                    MethodCallExpression call = new MethodCallExpression(left, "compareTo", new ArgumentListExpression(right));
                    call.setImplicitThis(false);
                    call.setMethodTarget(COMPARE_TO_METHOD);
                    call.setSourcePosition(bin);
                    CompareIdentityExpression compareIdentity = new CompareIdentityExpression(left, right);
                    compareIdentity.putNodeMetaData(StaticTypesMarker.INFERRED_RETURN_TYPE, ClassHelper.boolean_TYPE);
                    TernaryExpression result = new TernaryExpression(// a==b
                    new BooleanExpression(compareIdentity), CONSTANT_ZERO, new TernaryExpression(// a==null
                    new BooleanExpression(new CompareToNullExpression(left, true)), CONSTANT_MINUS_ONE, new TernaryExpression(// b==null
                    new BooleanExpression(new CompareToNullExpression(right, true)), CONSTANT_ONE, call)));
                    compareIdentity.putNodeMetaData(StaticTypesMarker.INFERRED_RETURN_TYPE, ClassHelper.int_TYPE);
                    result.putNodeMetaData(StaticTypesMarker.INFERRED_TYPE, ClassHelper.int_TYPE);
                    TernaryExpression expr = (TernaryExpression) result.getFalseExpression();
                    expr.putNodeMetaData(StaticTypesMarker.INFERRED_TYPE, ClassHelper.int_TYPE);
                    expr.getFalseExpression().putNodeMetaData(StaticTypesMarker.INFERRED_TYPE, ClassHelper.int_TYPE);
                    return result;
                }
            }
        }
        boolean isAssignment = StaticTypeCheckingSupport.isAssignment(operationType);
        MethodCallExpression call;
        MethodNode node = (MethodNode) list[0];
        String name = (String) list[1];
        Expression left = staticCompilationTransformer.transform(leftExpression);
        Expression right = staticCompilationTransformer.transform(rightExpression);
        BinaryExpression optimized = tryOptimizeCharComparison(left, right, bin);
        if (optimized != null) {
            optimized.removeNodeMetaData(BINARY_EXP_TARGET);
            return transformBinaryExpression(optimized);
        }
        call = new MethodCallExpression(left, name, new ArgumentListExpression(right));
        call.setImplicitThis(false);
        call.setMethodTarget(node);
        MethodNode adapter = StaticCompilationTransformer.BYTECODE_BINARY_ADAPTERS.get(operationType);
        if (adapter != null) {
            ClassExpression sba = new ClassExpression(StaticCompilationTransformer.BYTECODE_ADAPTER_CLASS);
            // replace with compareEquals
            call = new MethodCallExpression(sba, "compareEquals", new ArgumentListExpression(left, right));
            call.setMethodTarget(adapter);
            call.setImplicitThis(false);
        }
        call.setSourcePosition(bin);
        if (!isAssignment)
            return call;
        // the method represents the operation type only, and we must add an assignment
        return new BinaryExpression(left, Token.newSymbol("=", operation.getStartLine(), operation.getStartColumn()), call);
    }
    if (bin.getOperation().getType() == Types.EQUAL && leftExpression instanceof TupleExpression && rightExpression instanceof ListExpression) {
        // multiple assignment
        ListOfExpressionsExpression cle = new ListOfExpressionsExpression();
        boolean isDeclaration = bin instanceof DeclarationExpression;
        List<Expression> leftExpressions = ((TupleExpression) leftExpression).getExpressions();
        List<Expression> rightExpressions = ((ListExpression) rightExpression).getExpressions();
        Iterator<Expression> leftIt = leftExpressions.iterator();
        Iterator<Expression> rightIt = rightExpressions.iterator();
        if (isDeclaration) {
            while (leftIt.hasNext()) {
                Expression left = leftIt.next();
                if (rightIt.hasNext()) {
                    Expression right = rightIt.next();
                    BinaryExpression bexp = new DeclarationExpression(left, bin.getOperation(), right);
                    bexp.setSourcePosition(right);
                    cle.addExpression(bexp);
                }
            }
        } else {
            // (next, result) = [ result, next+result ]
            // -->
            // def tmp1 = result
            // def tmp2 = next+result
            // next = tmp1
            // result = tmp2
            int size = rightExpressions.size();
            List<Expression> tmpAssignments = new ArrayList<Expression>(size);
            List<Expression> finalAssignments = new ArrayList<Expression>(size);
            for (int i = 0; i < Math.min(size, leftExpressions.size()); i++) {
                Expression left = leftIt.next();
                Expression right = rightIt.next();
                VariableExpression tmpVar = new VariableExpression("$tmpVar$" + tmpVarCounter++);
                BinaryExpression bexp = new DeclarationExpression(tmpVar, bin.getOperation(), right);
                bexp.setSourcePosition(right);
                tmpAssignments.add(bexp);
                bexp = new BinaryExpression(left, bin.getOperation(), new VariableExpression(tmpVar));
                bexp.setSourcePosition(left);
                finalAssignments.add(bexp);
            }
            for (Expression tmpAssignment : tmpAssignments) {
                cle.addExpression(tmpAssignment);
            }
            for (Expression finalAssignment : finalAssignments) {
                cle.addExpression(finalAssignment);
            }
        }
        return staticCompilationTransformer.transform(cle);
    }
    return staticCompilationTransformer.superTransform(bin);
}
Also used : TernaryExpression(org.codehaus.groovy.ast.expr.TernaryExpression) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) TupleExpression(org.codehaus.groovy.ast.expr.TupleExpression) ArrayList(java.util.ArrayList) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) Token(org.codehaus.groovy.syntax.Token) BooleanExpression(org.codehaus.groovy.ast.expr.BooleanExpression) ListOfExpressionsExpression(org.codehaus.groovy.transform.sc.ListOfExpressionsExpression) MethodNode(org.codehaus.groovy.ast.MethodNode) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) BinaryExpression(org.codehaus.groovy.ast.expr.BinaryExpression) PropertyExpression(org.codehaus.groovy.ast.expr.PropertyExpression) ClassNode(org.codehaus.groovy.ast.ClassNode) DeclarationExpression(org.codehaus.groovy.ast.expr.DeclarationExpression) ListExpression(org.codehaus.groovy.ast.expr.ListExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) ListExpression(org.codehaus.groovy.ast.expr.ListExpression) BooleanExpression(org.codehaus.groovy.ast.expr.BooleanExpression) PropertyExpression(org.codehaus.groovy.ast.expr.PropertyExpression) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) Expression(org.codehaus.groovy.ast.expr.Expression) ListOfExpressionsExpression(org.codehaus.groovy.transform.sc.ListOfExpressionsExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) DeclarationExpression(org.codehaus.groovy.ast.expr.DeclarationExpression) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) TupleExpression(org.codehaus.groovy.ast.expr.TupleExpression) BinaryExpression(org.codehaus.groovy.ast.expr.BinaryExpression) TernaryExpression(org.codehaus.groovy.ast.expr.TernaryExpression) StaticTypesTypeChooser(org.codehaus.groovy.classgen.asm.sc.StaticTypesTypeChooser)

Example 92 with ClassExpression

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

the class StaticMethodCallExpressionTransformer method transformStaticMethodCallExpression.

Expression transformStaticMethodCallExpression(final StaticMethodCallExpression orig) {
    MethodNode target = (MethodNode) orig.getNodeMetaData(StaticTypesMarker.DIRECT_METHOD_CALL_TARGET);
    if (target != null) {
        MethodCallExpression call = new MethodCallExpression(new ClassExpression(orig.getOwnerType()), orig.getMethod(), orig.getArguments());
        call.setMethodTarget(target);
        call.setSourcePosition(orig);
        call.copyNodeMetaData(orig);
        return transformer.transform(call);
    }
    return transformer.superTransform(orig);
}
Also used : MethodNode(org.codehaus.groovy.ast.MethodNode) StaticMethodCallExpression(org.codehaus.groovy.ast.expr.StaticMethodCallExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression)

Example 93 with ClassExpression

use of org.codehaus.groovy.ast.expr.ClassExpression in project gradle by gradle.

the class GradleResolveVisitor method transformBinaryExpression.

protected Expression transformBinaryExpression(BinaryExpression be) {
    Expression left = transform(be.getLeftExpression());
    int type = be.getOperation().getType();
    if ((type == Types.ASSIGNMENT_OPERATOR || type == Types.EQUAL) && left instanceof ClassExpression) {
        ClassExpression ce = (ClassExpression) left;
        String error = "you tried to assign a value to the class '" + ce.getType().getName() + "'";
        if (ce.getType().isScript()) {
            error += ". Do you have a script with this name?";
        }
        addError(error, be.getLeftExpression());
        return be;
    }
    if (left instanceof ClassExpression && isLeftSquareBracket(type)) {
        if (be.getRightExpression() instanceof ListExpression) {
            ListExpression list = (ListExpression) be.getRightExpression();
            if (list.getExpressions().isEmpty()) {
                // we have C[] if the list is empty -> should be an array then!
                final ClassExpression ce = new ClassExpression(left.getType().makeArray());
                ce.setSourcePosition(be);
                return ce;
            } else {
                // may be we have C[k1:v1, k2:v2] -> should become (C)([k1:v1, k2:v2])
                boolean map = true;
                for (Expression expression : list.getExpressions()) {
                    if (!(expression instanceof MapEntryExpression)) {
                        map = false;
                        break;
                    }
                }
                if (map) {
                    final MapExpression me = new MapExpression();
                    for (Expression expression : list.getExpressions()) {
                        me.addMapEntryExpression((MapEntryExpression) transform(expression));
                    }
                    me.setSourcePosition(list);
                    final CastExpression ce = new CastExpression(left.getType(), me);
                    ce.setSourcePosition(be);
                    return ce;
                }
            }
        } else if (be.getRightExpression() instanceof SpreadMapExpression) {
            // we have C[*:map] -> should become (C) map
            SpreadMapExpression mapExpression = (SpreadMapExpression) be.getRightExpression();
            Expression right = transform(mapExpression.getExpression());
            Expression ce = new CastExpression(left.getType(), right);
            ce.setSourcePosition(be);
            return ce;
        }
        if (be.getRightExpression() instanceof MapEntryExpression) {
            // may be we have C[k1:v1] -> should become (C)([k1:v1])
            final MapExpression me = new MapExpression();
            me.addMapEntryExpression((MapEntryExpression) transform(be.getRightExpression()));
            me.setSourcePosition(be.getRightExpression());
            final CastExpression ce = new CastExpression(left.getType(), me);
            ce.setSourcePosition(be);
            return ce;
        }
    }
    Expression right = transform(be.getRightExpression());
    be.setLeftExpression(left);
    be.setRightExpression(right);
    return be;
}
Also used : MapExpression(org.codehaus.groovy.ast.expr.MapExpression) SpreadMapExpression(org.codehaus.groovy.ast.expr.SpreadMapExpression) MapEntryExpression(org.codehaus.groovy.ast.expr.MapEntryExpression) ListExpression(org.codehaus.groovy.ast.expr.ListExpression) MapExpression(org.codehaus.groovy.ast.expr.MapExpression) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) BinaryExpression(org.codehaus.groovy.ast.expr.BinaryExpression) CastExpression(org.codehaus.groovy.ast.expr.CastExpression) PropertyExpression(org.codehaus.groovy.ast.expr.PropertyExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) Expression(org.codehaus.groovy.ast.expr.Expression) SpreadMapExpression(org.codehaus.groovy.ast.expr.SpreadMapExpression) ConstructorCallExpression(org.codehaus.groovy.ast.expr.ConstructorCallExpression) AnnotationConstantExpression(org.codehaus.groovy.ast.expr.AnnotationConstantExpression) DeclarationExpression(org.codehaus.groovy.ast.expr.DeclarationExpression) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) MapEntryExpression(org.codehaus.groovy.ast.expr.MapEntryExpression) ListExpression(org.codehaus.groovy.ast.expr.ListExpression) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) CastExpression(org.codehaus.groovy.ast.expr.CastExpression) SpreadMapExpression(org.codehaus.groovy.ast.expr.SpreadMapExpression)

Example 94 with ClassExpression

use of org.codehaus.groovy.ast.expr.ClassExpression in project gradle by gradle.

the class GradleResolveVisitor method transformDeclarationExpression.

protected Expression transformDeclarationExpression(DeclarationExpression de) {
    visitAnnotations(de);
    Expression oldLeft = de.getLeftExpression();
    checkingVariableTypeInDeclaration = true;
    Expression left = transform(oldLeft);
    checkingVariableTypeInDeclaration = false;
    if (left instanceof ClassExpression) {
        ClassExpression ce = (ClassExpression) left;
        addError("you tried to assign a value to the class " + ce.getType().getName(), oldLeft);
        return de;
    }
    Expression right = transform(de.getRightExpression());
    if (right == de.getRightExpression()) {
        fixDeclaringClass(de);
        return de;
    }
    DeclarationExpression newDeclExpr = new DeclarationExpression(left, de.getOperation(), right);
    newDeclExpr.setDeclaringClass(de.getDeclaringClass());
    fixDeclaringClass(newDeclExpr);
    newDeclExpr.setSourcePosition(de);
    newDeclExpr.addAnnotations(de.getAnnotations());
    return newDeclExpr;
}
Also used : ListExpression(org.codehaus.groovy.ast.expr.ListExpression) MapExpression(org.codehaus.groovy.ast.expr.MapExpression) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) BinaryExpression(org.codehaus.groovy.ast.expr.BinaryExpression) CastExpression(org.codehaus.groovy.ast.expr.CastExpression) PropertyExpression(org.codehaus.groovy.ast.expr.PropertyExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) Expression(org.codehaus.groovy.ast.expr.Expression) SpreadMapExpression(org.codehaus.groovy.ast.expr.SpreadMapExpression) ConstructorCallExpression(org.codehaus.groovy.ast.expr.ConstructorCallExpression) AnnotationConstantExpression(org.codehaus.groovy.ast.expr.AnnotationConstantExpression) DeclarationExpression(org.codehaus.groovy.ast.expr.DeclarationExpression) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) MapEntryExpression(org.codehaus.groovy.ast.expr.MapEntryExpression) DeclarationExpression(org.codehaus.groovy.ast.expr.DeclarationExpression) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression)

Example 95 with ClassExpression

use of org.codehaus.groovy.ast.expr.ClassExpression in project gradle by gradle.

the class GradleResolveVisitor method correctClassClassChain.

// iterate from the inner most to the outer and check for classes
// this check will ignore a .class property, for Example Integer.class will be
// a PropertyExpression with the ClassExpression of Integer as objectExpression
// and class as property
private Expression correctClassClassChain(PropertyExpression pe) {
    LinkedList<Expression> stack = new LinkedList<Expression>();
    ClassExpression found = null;
    for (Expression it = pe; it != null; it = ((PropertyExpression) it).getObjectExpression()) {
        if (it instanceof ClassExpression) {
            found = (ClassExpression) it;
            break;
        } else if (!(it.getClass() == PropertyExpression.class)) {
            return pe;
        }
        stack.addFirst(it);
    }
    if (found == null) {
        return pe;
    }
    if (stack.isEmpty()) {
        return pe;
    }
    Object stackElement = stack.removeFirst();
    if (!(stackElement.getClass() == PropertyExpression.class)) {
        return pe;
    }
    PropertyExpression classPropertyExpression = (PropertyExpression) stackElement;
    String propertyNamePart = classPropertyExpression.getPropertyAsString();
    if (propertyNamePart == null || !propertyNamePart.equals("class")) {
        return pe;
    }
    found.setSourcePosition(classPropertyExpression);
    if (stack.isEmpty()) {
        return found;
    }
    stackElement = stack.removeFirst();
    if (!(stackElement.getClass() == PropertyExpression.class)) {
        return pe;
    }
    PropertyExpression classPropertyExpressionContainer = (PropertyExpression) stackElement;
    classPropertyExpressionContainer.setObjectExpression(found);
    return pe;
}
Also used : ListExpression(org.codehaus.groovy.ast.expr.ListExpression) MapExpression(org.codehaus.groovy.ast.expr.MapExpression) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) BinaryExpression(org.codehaus.groovy.ast.expr.BinaryExpression) CastExpression(org.codehaus.groovy.ast.expr.CastExpression) PropertyExpression(org.codehaus.groovy.ast.expr.PropertyExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) Expression(org.codehaus.groovy.ast.expr.Expression) SpreadMapExpression(org.codehaus.groovy.ast.expr.SpreadMapExpression) ConstructorCallExpression(org.codehaus.groovy.ast.expr.ConstructorCallExpression) AnnotationConstantExpression(org.codehaus.groovy.ast.expr.AnnotationConstantExpression) DeclarationExpression(org.codehaus.groovy.ast.expr.DeclarationExpression) ClosureExpression(org.codehaus.groovy.ast.expr.ClosureExpression) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) MapEntryExpression(org.codehaus.groovy.ast.expr.MapEntryExpression) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) PropertyExpression(org.codehaus.groovy.ast.expr.PropertyExpression) LinkedList(java.util.LinkedList)

Aggregations

ClassExpression (org.codehaus.groovy.ast.expr.ClassExpression)97 Expression (org.codehaus.groovy.ast.expr.Expression)59 VariableExpression (org.codehaus.groovy.ast.expr.VariableExpression)57 ConstantExpression (org.codehaus.groovy.ast.expr.ConstantExpression)55 MethodCallExpression (org.codehaus.groovy.ast.expr.MethodCallExpression)52 ClassNode (org.codehaus.groovy.ast.ClassNode)48 ArgumentListExpression (org.codehaus.groovy.ast.expr.ArgumentListExpression)41 ListExpression (org.codehaus.groovy.ast.expr.ListExpression)40 PropertyExpression (org.codehaus.groovy.ast.expr.PropertyExpression)37 BinaryExpression (org.codehaus.groovy.ast.expr.BinaryExpression)33 ConstructorCallExpression (org.codehaus.groovy.ast.expr.ConstructorCallExpression)31 ClosureExpression (org.codehaus.groovy.ast.expr.ClosureExpression)27 MethodNode (org.codehaus.groovy.ast.MethodNode)18 DeclarationExpression (org.codehaus.groovy.ast.expr.DeclarationExpression)17 StaticMethodCallExpression (org.codehaus.groovy.ast.expr.StaticMethodCallExpression)17 TupleExpression (org.codehaus.groovy.ast.expr.TupleExpression)17 AnnotationNode (org.codehaus.groovy.ast.AnnotationNode)16 InnerClassNode (org.codehaus.groovy.ast.InnerClassNode)16 CastExpression (org.codehaus.groovy.ast.expr.CastExpression)16 FieldNode (org.codehaus.groovy.ast.FieldNode)15