Search in sources :

Example 1 with AssignmentOperatorTranslation

use of org.eclipse.ceylon.compiler.java.codegen.Operators.AssignmentOperatorTranslation in project ceylon by eclipse.

the class ExpressionTransformer method transform.

public JCExpression transform(final Tree.BitwiseAssignmentOp op) {
    final AssignmentOperatorTranslation operator = Operators.getAssignmentOperator(op.getClass());
    if (operator == null) {
        return makeErroneous(op, "compiler bug: " + op.getNodeType() + " is not a supported bitwise assignment operator");
    }
    Type valueType = op.getLeftTerm().getTypeModel();
    final Type rightType = getSupertype(op.getRightTerm(), typeFact().getSetDeclaration());
    return transformAssignAndReturnOperation(op, op.getLeftTerm(), false, valueType, valueType, new AssignAndReturnOperationFactory() {

        @Override
        public JCExpression getNewValue(JCExpression previousValue) {
            JCExpression result = transformOverridableBinaryOperator(op, op.getLeftTerm(), op.getRightTerm(), rightType, operator.binaryOperator, OptimisationStrategy.NONE, previousValue, op.getTypeModel());
            return result;
        }
    });
}
Also used : UnionType(org.eclipse.ceylon.model.typechecker.model.UnionType) Type(org.eclipse.ceylon.model.typechecker.model.Type) JCExpression(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression) AssignmentOperatorTranslation(org.eclipse.ceylon.compiler.java.codegen.Operators.AssignmentOperatorTranslation)

Example 2 with AssignmentOperatorTranslation

use of org.eclipse.ceylon.compiler.java.codegen.Operators.AssignmentOperatorTranslation in project ceylon by eclipse.

the class ExpressionTransformer method transform.

public JCExpression transform(final Tree.LogicalAssignmentOp op) {
    final AssignmentOperatorTranslation operator = Operators.getAssignmentOperator(op.getClass());
    if (operator == null) {
        return makeErroneous(op, "compiler bug: " + op.getNodeType() + " is not a supported logical assignment operator");
    }
    // optimise if we can
    if (CodegenUtil.isDirectAccessVariable(op.getLeftTerm())) {
        return optimiseAssignmentOperator(op, operator);
    }
    Type valueType = op.getLeftTerm().getTypeModel();
    // we work on unboxed types
    return transformAssignAndReturnOperation(op, op.getLeftTerm(), false, valueType, valueType, new AssignAndReturnOperationFactory() {

        @Override
        public JCExpression getNewValue(JCExpression previousValue) {
            // make this call: previousValue OP RHS
            return transformLogicalOp(op, operator.binaryOperator, previousValue, op.getRightTerm());
        }
    });
}
Also used : UnionType(org.eclipse.ceylon.model.typechecker.model.UnionType) Type(org.eclipse.ceylon.model.typechecker.model.Type) JCExpression(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression) AssignmentOperatorTranslation(org.eclipse.ceylon.compiler.java.codegen.Operators.AssignmentOperatorTranslation)

Example 3 with AssignmentOperatorTranslation

use of org.eclipse.ceylon.compiler.java.codegen.Operators.AssignmentOperatorTranslation in project ceylon by eclipse.

the class ExpressionTransformer method transform.

// 
// Operator-Assignment expressions
public JCExpression transform(final Tree.ArithmeticAssignmentOp op) {
    final AssignmentOperatorTranslation operator = Operators.getAssignmentOperator(op.getClass());
    if (operator == null) {
        return makeErroneous(op, "compiler bug: " + op.getNodeType() + " is not a supported arithmetic assignment operator");
    }
    // see if we can optimise it
    if (op.getUnboxed() && CodegenUtil.isDirectAccessVariable(op.getLeftTerm())) {
        return optimiseAssignmentOperator(op, operator);
    }
    // we can use unboxed types if both operands are unboxed
    final boolean boxResult = !op.getUnboxed();
    // find the proper type
    Interface compoundType = op.getUnit().getNumericDeclaration();
    if (op instanceof Tree.AddAssignOp) {
        compoundType = op.getUnit().getSummableDeclaration();
    } else if (op instanceof Tree.SubtractAssignOp) {
        compoundType = op.getUnit().getInvertableDeclaration();
    } else if (op instanceof Tree.RemainderAssignOp) {
        compoundType = op.getUnit().getIntegralDeclaration();
    }
    final Type leftType = getSupertype(op.getLeftTerm(), compoundType);
    // Normally we don't look at the RHS type because it can lead to unknown types, but if we want to extract its
    // underlying type we have to, and we deal with any eventual unknown type. Presumably unknown types will not have
    // any useful underlying type anyways.
    // Note  that looking at the RHS allows us to not have the issue of using the LHS type wrongly for the RHS type when
    // the LHS type is Float and the RHS type is Integer with implicit Float coercion
    Type rightSupertype = getSupertype(op.getRightTerm(), compoundType);
    if (rightSupertype == null || rightSupertype.isUnknown()) {
        // supertype could be null if, e.g. right type is Nothing
        rightSupertype = leftType;
    }
    Type rightTypeArgument = getTypeArgument(rightSupertype);
    if (rightTypeArgument == null || rightTypeArgument.isUnknown())
        rightTypeArgument = getTypeArgument(leftType);
    final Type rightType = getMostPreciseType(op.getLeftTerm(), rightTypeArgument);
    final Type resultType = getLeastPreciseType(op.getLeftTerm(), op.getRightTerm());
    // we work on boxed types
    return transformAssignAndReturnOperation(op, op.getLeftTerm(), boxResult, op.getLeftTerm().getTypeModel(), resultType, new AssignAndReturnOperationFactory() {

        @Override
        public JCExpression getNewValue(JCExpression previousValue) {
            // make this call: previousValue OP RHS
            JCExpression ret = transformOverridableBinaryOperator(op, op.getLeftTerm(), op.getRightTerm(), rightType, operator.binaryOperator, boxResult ? OptimisationStrategy.NONE : OptimisationStrategy.OPTIMISE, previousValue, op.getTypeModel());
            return ret;
        }
    });
}
Also used : UnionType(org.eclipse.ceylon.model.typechecker.model.UnionType) Type(org.eclipse.ceylon.model.typechecker.model.Type) JCExpression(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression) AssignmentOperatorTranslation(org.eclipse.ceylon.compiler.java.codegen.Operators.AssignmentOperatorTranslation) JCTree(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) Interface(org.eclipse.ceylon.model.typechecker.model.Interface) ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) LazyInterface(org.eclipse.ceylon.model.loader.model.LazyInterface)

Aggregations

AssignmentOperatorTranslation (org.eclipse.ceylon.compiler.java.codegen.Operators.AssignmentOperatorTranslation)3 JCExpression (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression)3 Type (org.eclipse.ceylon.model.typechecker.model.Type)3 UnionType (org.eclipse.ceylon.model.typechecker.model.UnionType)3 Tree (org.eclipse.ceylon.compiler.typechecker.tree.Tree)1 JCTree (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree)1 LazyInterface (org.eclipse.ceylon.model.loader.model.LazyInterface)1 ClassOrInterface (org.eclipse.ceylon.model.typechecker.model.ClassOrInterface)1 Interface (org.eclipse.ceylon.model.typechecker.model.Interface)1