Search in sources :

Example 1 with Term

use of org.eclipse.ceylon.compiler.typechecker.tree.Tree.Term in project ceylon by eclipse.

the class ExpressionTransformer method knownNullSafe.

private static boolean knownNullSafe(Tree.Term term) {
    if (term instanceof Tree.InvocationExpression) {
        Tree.InvocationExpression ie = (Tree.InvocationExpression) term;
        Tree.Term p = ie.getPrimary();
        if (p instanceof Tree.StaticMemberOrTypeExpression) {
            Tree.StaticMemberOrTypeExpression bme = (Tree.StaticMemberOrTypeExpression) p;
            Declaration dec = bme.getDeclaration();
            if (dec != null) {
                String qname = dec.getQualifiedNameString();
                return knownNullSafe.contains(qname);
            }
        }
    }
    return false;
}
Also used : Term(org.eclipse.ceylon.compiler.typechecker.tree.Tree.Term) JCTree(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration)

Example 2 with Term

use of org.eclipse.ceylon.compiler.typechecker.tree.Tree.Term in project ceylon by eclipse.

the class ExpressionTransformer method transform.

// Prefix operator
public JCExpression transform(final Tree.PrefixOperatorExpression expr) {
    final OperatorTranslation operator = Operators.getOperator(expr.getClass());
    if (operator == null) {
        return makeErroneous(expr, "compiler bug: " + expr.getNodeType() + " is not supported yet");
    }
    OptimisationStrategy optimisationStrategy = operator.getUnOpOptimisationStrategy(expr, expr.getTerm(), this);
    final boolean canOptimise = optimisationStrategy.useJavaOperator();
    Tree.Term term = expr.getTerm();
    // only fully optimise if we don't have to access the getter/setter
    if (canOptimise && CodegenUtil.isDirectAccessVariable(term)) {
        JCExpression jcTerm = transformExpression(term, BoxingStrategy.UNBOXED, expr.getTypeModel(), EXPR_WIDEN_PRIM);
        return at(expr).Unary(operator.javacOperator, jcTerm);
    }
    // Interface compoundType = expr.getUnit().getOrdinalDeclaration();
    // Type valueType = getSupertype(term, compoundType);
    // getMostPreciseType(term, getTypeArgument(valueType, 0));
    final Type returnType = term.getTypeModel();
    // we work on boxed types unless we could have optimised
    return transformAssignAndReturnOperation(expr, term, !canOptimise, term.getTypeModel(), returnType, new AssignAndReturnOperationFactory() {

        @Override
        public JCExpression getNewValue(JCExpression previousValue) {
            // use +1/-1 if we can optimise a bit
            if (canOptimise) {
                JCExpression ret = make().Binary(operator == OperatorTranslation.UNARY_PREFIX_INCREMENT ? JCTree.Tag.PLUS : JCTree.Tag.MINUS, previousValue, makeInteger(1));
                ret = unAutoPromote(ret, returnType, expr.getSmall());
                return ret;
            }
            // make this call: previousValue.getSuccessor() or previousValue.getPredecessor()
            return make().Apply(null, makeSelect(previousValue, operator.getCeylonMethodName()), List.<JCExpression>nil());
        }
    });
}
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) Term(org.eclipse.ceylon.compiler.typechecker.tree.Tree.Term) JCTree(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) OptimisationStrategy(org.eclipse.ceylon.compiler.java.codegen.Operators.OptimisationStrategy) OperatorTranslation(org.eclipse.ceylon.compiler.java.codegen.Operators.OperatorTranslation) AssignmentOperatorTranslation(org.eclipse.ceylon.compiler.java.codegen.Operators.AssignmentOperatorTranslation)

Example 3 with Term

use of org.eclipse.ceylon.compiler.typechecker.tree.Tree.Term in project ceylon by eclipse.

the class ExpressionTransformer method transform.

public JCExpression transform(Tree.DefaultOp op) {
    Term elseTerm = unwrapExpressionUntilTerm(op.getRightTerm());
    Type typeModel = typeFact().denotableType(op.getTypeModel());
    // make sure we do not insert null checks if we're going to allow testing for null
    Type rightExpectedType = getOptionalTypeForInteropIfAllowed(expectedType, typeModel, elseTerm);
    if (unwrapExpressionUntilTerm(op.getLeftTerm()) instanceof Tree.ThenOp) {
        // Optimize cond then foo else bar (avoids unnecessary boxing in particular)
        Tree.ThenOp then = (Tree.ThenOp) unwrapExpressionUntilTerm(op.getLeftTerm());
        Term condTerm = then.getLeftTerm();
        Term thenTerm = then.getRightTerm();
        JCExpression cond = transformExpression(condTerm, BoxingStrategy.UNBOXED, condTerm.getTypeModel());
        JCExpression thenpart = transformExpression(thenTerm, CodegenUtil.getBoxingStrategy(op), rightExpectedType);
        JCExpression elsepart = transformExpression(elseTerm, CodegenUtil.getBoxingStrategy(op), rightExpectedType);
        return make().Conditional(cond, thenpart, elsepart);
    }
    JCExpression left = transformExpression(op.getLeftTerm(), BoxingStrategy.BOXED, typeFact().getOptionalType(typeModel));
    JCExpression right = transformExpression(elseTerm, BoxingStrategy.BOXED, rightExpectedType);
    Naming.SyntheticName varName = naming.temp();
    JCExpression varIdent = varName.makeIdent();
    JCExpression test = at(op).Binary(JCTree.Tag.NE, varIdent, makeNull());
    JCExpression cond = make().Conditional(test, varIdent, right);
    JCExpression typeExpr = makeJavaType(typeModel, JT_NO_PRIMITIVES);
    return makeLetExpr(varName, null, typeExpr, left, cond);
}
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) JCTree(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) SyntheticName(org.eclipse.ceylon.compiler.java.codegen.Naming.SyntheticName) Term(org.eclipse.ceylon.compiler.typechecker.tree.Tree.Term) TreeUtil.unwrapExpressionUntilTerm(org.eclipse.ceylon.compiler.typechecker.tree.TreeUtil.unwrapExpressionUntilTerm)

Example 4 with Term

use of org.eclipse.ceylon.compiler.typechecker.tree.Tree.Term in project ceylon by eclipse.

the class ExpressionTransformer method transformArg.

protected final JCExpression transformArg(SimpleInvocation invocation, int argIndex) {
    final Tree.Term expr = invocation.getArgumentExpression(argIndex);
    if (invocation.hasParameter(argIndex)) {
        Type type = invocation.getParameterType(argIndex);
        if (invocation.isParameterSequenced(argIndex) && // Java methods need their underlying type preserved
        !invocation.isJavaVariadicMethod()) {
            if (!invocation.isArgumentSpread(argIndex)) {
                // If the parameter is sequenced and the argument is not ...
                // then the expected type of the *argument* is the type arg to Iterator
                type = typeFact().getIteratedType(type);
            } else if (invocation.getArgumentType(argIndex).getSupertype(typeFact().getSequentialDeclaration()) == null) {
                // On the other hand, if the parameter is sequenced and the argument is spread,
                // but not sequential, then transformArguments() will use getSequence(),
                // so we only need to expect an Iterable type
                type = org.eclipse.ceylon.model.typechecker.model.ModelUtil.appliedType(typeFact().getIterableDeclaration(), typeFact().getIteratedType(type), typeFact().getIteratedAbsentType(type));
            }
        }
        BoxingStrategy boxingStrategy = invocation.getParameterBoxingStrategy(argIndex);
        int flags = 0;
        if (!invocation.isParameterRaw(argIndex))
            flags |= ExpressionTransformer.EXPR_EXPECTED_TYPE_NOT_RAW;
        if (invocation.isParameterWithConstrainedTypeParameters(argIndex))
            flags |= ExpressionTransformer.EXPR_EXPECTED_TYPE_HAS_CONSTRAINED_TYPE_PARAMETERS;
        if (invocation.isParameterWithDependentCovariantTypeParameters(argIndex))
            flags |= ExpressionTransformer.EXPR_EXPECTED_TYPE_HAS_DEPENDENT_COVARIANT_TYPE_PARAMETERS;
        if (invocation.erasedArgument(unwrapExpressionUntilTerm(expr))) {
            flags |= EXPR_DOWN_CAST;
        }
        if (!expr.getSmall() && invocation.getParameterSmall(argIndex)) {
            flags |= ExpressionTransformer.EXPR_UNSAFE_PRIMITIVE_TYPECAST_OK;
        }
        boolean coerced = invocation.isParameterCoerced(argIndex);
        if (coerced) {
            flags |= ExpressionTransformer.EXPR_IS_COERCED;
            if (invocation.isParameterJavaVariadic(argIndex) && type.isSequential()) {
                type = typeFact().getSequentialElementType(type);
            }
        }
        JCExpression ret = transformExpression(expr, boxingStrategy, type, flags);
        // We can coerce most SAMs in transformExpression, EXCEPT invocation
        // calls which we do here.
        Term term = Decl.unwrapExpressionsUntilTerm(expr);
        if (coerced && term instanceof Tree.InvocationExpression && isFunctionalResult(term.getTypeModel()) && checkForFunctionalInterface(type) != null) {
            return transformFunctionalInterfaceBridge((Tree.InvocationExpression) term, ret, type);
        }
        return ret;
    } else {
        // Overloaded methods don't have a reference to a parameter
        // so we have to treat them differently. Also knowing it's
        // overloaded we know we're dealing with Java code so we unbox
        Type type = expr.getTypeModel();
        return expressionGen().transformExpression(expr, BoxingStrategy.UNBOXED, type);
    }
}
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) Term(org.eclipse.ceylon.compiler.typechecker.tree.Tree.Term) JCTree(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) Term(org.eclipse.ceylon.compiler.typechecker.tree.Tree.Term) TreeUtil.unwrapExpressionUntilTerm(org.eclipse.ceylon.compiler.typechecker.tree.TreeUtil.unwrapExpressionUntilTerm)

Example 5 with Term

use of org.eclipse.ceylon.compiler.typechecker.tree.Tree.Term in project ceylon by eclipse.

the class ExpressionTransformer method checkForByteLiterals.

private JCExpression checkForByteLiterals(Tree.InvocationExpression ce) {
    // same test as in BoxingVisitor.isByteLiteral()
    if (ce.getPrimary() instanceof Tree.BaseTypeExpression && ce.getPositionalArgumentList() != null) {
        java.util.List<Tree.PositionalArgument> positionalArguments = ce.getPositionalArgumentList().getPositionalArguments();
        if (positionalArguments.size() == 1) {
            PositionalArgument argument = positionalArguments.get(0);
            if (argument instanceof Tree.ListedArgument && ((Tree.ListedArgument) argument).getExpression() != null) {
                Term term = ((Tree.ListedArgument) argument).getExpression().getTerm();
                boolean negative = false;
                if (term instanceof Tree.NegativeOp) {
                    negative = true;
                    term = ((Tree.NegativeOp) term).getTerm();
                }
                if (term instanceof Tree.NaturalLiteral) {
                    Declaration decl = ((Tree.BaseTypeExpression) ce.getPrimary()).getDeclaration();
                    if (decl instanceof Class) {
                        if (((Class) decl).isByte()) {
                            at(ce);
                            try {
                                long value = literalValue((Tree.NaturalLiteral) term).longValue();
                                if (negative)
                                    value = -value;
                                // assignment, not for method calls, so it's simpler to always cast
                                return make().TypeCast(syms().byteType, make().Literal(value));
                            } catch (ErroneousException e) {
                                // replaced with a throw.
                                return e.makeErroneous(this);
                            }
                        }
                    }
                }
            }
        }
    }
    return null;
}
Also used : PositionalArgument(org.eclipse.ceylon.compiler.typechecker.tree.Tree.PositionalArgument) Term(org.eclipse.ceylon.compiler.typechecker.tree.Tree.Term) TreeUtil.unwrapExpressionUntilTerm(org.eclipse.ceylon.compiler.typechecker.tree.TreeUtil.unwrapExpressionUntilTerm) JCTree(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) JCNewClass(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCNewClass) Class(org.eclipse.ceylon.model.typechecker.model.Class) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration)

Aggregations

Term (org.eclipse.ceylon.compiler.typechecker.tree.Tree.Term)29 Tree (org.eclipse.ceylon.compiler.typechecker.tree.Tree)27 JCTree (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree)14 Declaration (org.eclipse.ceylon.model.typechecker.model.Declaration)11 Type (org.eclipse.ceylon.model.typechecker.model.Type)11 TypedDeclaration (org.eclipse.ceylon.model.typechecker.model.TypedDeclaration)11 JCExpression (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression)10 TypeDeclaration (org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)10 Expression (org.eclipse.ceylon.compiler.typechecker.tree.Tree.Expression)6 Function (org.eclipse.ceylon.model.typechecker.model.Function)6 UnionType (org.eclipse.ceylon.model.typechecker.model.UnionType)6 AttributeDeclaration (org.eclipse.ceylon.compiler.typechecker.tree.Tree.AttributeDeclaration)5 TreeUtil.unwrapExpressionUntilTerm (org.eclipse.ceylon.compiler.typechecker.tree.TreeUtil.unwrapExpressionUntilTerm)5 BaseMemberExpression (org.eclipse.ceylon.compiler.typechecker.tree.Tree.BaseMemberExpression)4 ExtendedType (org.eclipse.ceylon.compiler.typechecker.tree.Tree.ExtendedType)4 LazySpecifierExpression (org.eclipse.ceylon.compiler.typechecker.tree.Tree.LazySpecifierExpression)4 IntersectionType (org.eclipse.ceylon.model.typechecker.model.IntersectionType)4 SyntheticName (org.eclipse.ceylon.compiler.java.codegen.Naming.SyntheticName)3 AssignmentOperatorTranslation (org.eclipse.ceylon.compiler.java.codegen.Operators.AssignmentOperatorTranslation)3 OperatorTranslation (org.eclipse.ceylon.compiler.java.codegen.Operators.OperatorTranslation)3