Search in sources :

Example 1 with Term

use of com.redhat.ceylon.compiler.typechecker.tree.Tree.Term in project ceylon-compiler by ceylon.

the class ExpressionTransformer method transform.

// Postfix operator
public JCExpression transform(Tree.PostfixOperatorExpression expr) {
    OperatorTranslation operator = Operators.getOperator(expr.getClass());
    if (operator == null) {
        return makeErroneous(expr, "compiler bug " + expr.getNodeType() + " is not yet supported");
    }
    OptimisationStrategy optimisationStrategy = operator.getUnOpOptimisationStrategy(expr, expr.getTerm(), this);
    boolean canOptimise = optimisationStrategy.useJavaOperator();
    // only fully optimise if we don't have to access the getter/setter
    if (canOptimise && CodegenUtil.isDirectAccessVariable(expr.getTerm())) {
        JCExpression term = transformExpression(expr.getTerm(), BoxingStrategy.UNBOXED, expr.getTypeModel(), EXPR_WIDEN_PRIM);
        return at(expr).Unary(operator.javacOperator, term);
    }
    Tree.Term term = unwrapExpressionUntilTerm(expr.getTerm());
    Interface compoundType = expr.getUnit().getOrdinalDeclaration();
    Type valueType = getSupertype(expr.getTerm(), compoundType);
    Type returnType = getMostPreciseType(term, getTypeArgument(valueType, 0));
    List<JCVariableDecl> decls = List.nil();
    List<JCStatement> stats = List.nil();
    JCExpression result = null;
    // we can optimise that case a bit sometimes
    boolean boxResult = !canOptimise;
    // (let $tmp = attr; attr = $tmp.getSuccessor(); $tmp;)
    if (term instanceof Tree.BaseMemberExpression || // special case for java statics Foo.attr where Foo does not need to be evaluated
    (term instanceof Tree.QualifiedMemberExpression && ((Tree.QualifiedMemberExpression) term).getStaticMethodReference())) {
        JCExpression getter;
        if (term instanceof Tree.BaseMemberExpression)
            getter = transform((Tree.BaseMemberExpression) term, null);
        else
            getter = transformMemberExpression((Tree.QualifiedMemberExpression) term, null, null);
        at(expr);
        // Type $tmp = attr
        JCExpression exprType = makeJavaType(returnType, boxResult ? JT_NO_PRIMITIVES : 0);
        Name varName = naming.tempName("op");
        // make sure we box the results if necessary
        getter = applyErasureAndBoxing(getter, term, boxResult ? BoxingStrategy.BOXED : BoxingStrategy.UNBOXED, returnType);
        JCVariableDecl tmpVar = make().VarDef(make().Modifiers(0), varName, exprType, getter);
        decls = decls.prepend(tmpVar);
        // attr = $tmp.getSuccessor()
        JCExpression successor;
        if (canOptimise) {
            // use +1/-1 if we can optimise a bit
            successor = make().Binary(operator == OperatorTranslation.UNARY_POSTFIX_INCREMENT ? JCTree.PLUS : JCTree.MINUS, make().Ident(varName), makeInteger(1));
            successor = unAutoPromote(successor, returnType);
        } else {
            successor = make().Apply(null, makeSelect(make().Ident(varName), operator.ceylonMethod), List.<JCExpression>nil());
            // make sure the result is boxed if necessary, the result of successor/predecessor is always boxed
            successor = boxUnboxIfNecessary(successor, true, term.getTypeModel(), CodegenUtil.getBoxingStrategy(term));
        }
        JCExpression assignment = transformAssignment(expr, term, successor);
        stats = stats.prepend(at(expr).Exec(assignment));
        // $tmp
        result = make().Ident(varName);
    } else if (term instanceof Tree.QualifiedMemberExpression) {
        // e.attr++
        // (let $tmpE = e, $tmpV = $tmpE.attr; $tmpE.attr = $tmpV.getSuccessor(); $tmpV;)
        Tree.QualifiedMemberExpression qualified = (Tree.QualifiedMemberExpression) term;
        boolean isSuper = isSuperOrSuperOf(qualified.getPrimary());
        boolean isPackage = isPackageQualified(qualified);
        // transform the primary, this will get us a boxed primary
        JCExpression e = transformQualifiedMemberPrimary(qualified);
        at(expr);
        // Type $tmpE = e
        JCExpression exprType = makeJavaType(qualified.getTarget().getQualifyingType(), JT_NO_PRIMITIVES);
        Name varEName = naming.tempName("opE");
        JCVariableDecl tmpEVar = make().VarDef(make().Modifiers(0), varEName, exprType, e);
        // Type $tmpV = $tmpE.attr
        JCExpression attrType = makeJavaType(returnType, boxResult ? JT_NO_PRIMITIVES : 0);
        Name varVName = naming.tempName("opV");
        JCExpression getter;
        if (isSuper) {
            getter = transformMemberExpression(qualified, transformSuper(qualified), null);
        } else if (isPackage) {
            getter = transformMemberExpression(qualified, null, null);
        } else {
            getter = transformMemberExpression(qualified, make().Ident(varEName), null);
        }
        // make sure we box the results if necessary
        getter = applyErasureAndBoxing(getter, term, boxResult ? BoxingStrategy.BOXED : BoxingStrategy.UNBOXED, returnType);
        JCVariableDecl tmpVVar = make().VarDef(make().Modifiers(0), varVName, attrType, getter);
        decls = decls.prepend(tmpVVar);
        if (!isSuper && !isPackage) {
            // define all the variables
            decls = decls.prepend(tmpEVar);
        }
        // $tmpE.attr = $tmpV.getSuccessor()
        JCExpression successor;
        if (canOptimise) {
            // use +1/-1 if we can optimise a bit
            successor = make().Binary(operator == OperatorTranslation.UNARY_POSTFIX_INCREMENT ? JCTree.PLUS : JCTree.MINUS, make().Ident(varVName), makeInteger(1));
            successor = unAutoPromote(successor, returnType);
        } else {
            successor = make().Apply(null, makeSelect(make().Ident(varVName), operator.ceylonMethod), List.<JCExpression>nil());
            // make sure the result is boxed if necessary, the result of successor/predecessor is always boxed
            successor = boxUnboxIfNecessary(successor, true, term.getTypeModel(), CodegenUtil.getBoxingStrategy(term));
        }
        JCExpression assignment = transformAssignment(expr, term, isSuper ? transformSuper(qualified) : make().Ident(varEName), successor);
        stats = stats.prepend(at(expr).Exec(assignment));
        // $tmpV
        result = make().Ident(varVName);
    } else {
        return makeErroneous(term, "compiler bug: " + term.getNodeType() + " is not supported yet");
    }
    return make().LetExpr(decls, stats, result);
}
Also used : Term(com.redhat.ceylon.compiler.typechecker.tree.Tree.Term) JCStatement(com.sun.tools.javac.tree.JCTree.JCStatement) JCVariableDecl(com.sun.tools.javac.tree.JCTree.JCVariableDecl) AssignmentOperatorTranslation(com.redhat.ceylon.compiler.java.codegen.Operators.AssignmentOperatorTranslation) OperatorTranslation(com.redhat.ceylon.compiler.java.codegen.Operators.OperatorTranslation) SyntheticName(com.redhat.ceylon.compiler.java.codegen.Naming.SyntheticName) Name(com.sun.tools.javac.util.Name) Type(com.redhat.ceylon.model.typechecker.model.Type) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) JCTree(com.sun.tools.javac.tree.JCTree) Tree(com.redhat.ceylon.compiler.typechecker.tree.Tree) OptimisationStrategy(com.redhat.ceylon.compiler.java.codegen.Operators.OptimisationStrategy) Interface(com.redhat.ceylon.model.typechecker.model.Interface) ClassOrInterface(com.redhat.ceylon.model.typechecker.model.ClassOrInterface)

Example 2 with Term

use of com.redhat.ceylon.compiler.typechecker.tree.Tree.Term in project ceylon-compiler by ceylon.

the class ExpressionTransformer method transformOverridableUnaryOperator.

private JCExpression transformOverridableUnaryOperator(Tree.UnaryOperatorExpression op, Type expectedType) {
    at(op);
    Tree.Term term = op.getTerm();
    OperatorTranslation operator = Operators.getOperator(op.getClass());
    if (operator == null) {
        return makeErroneous(op, "compiler bug: " + op.getClass() + " is an unhandled operator class");
    }
    JCExpression ret;
    if (operator.getUnOpOptimisationStrategy(op, op.getTerm(), this).useJavaOperator()) {
        // optimisation for unboxed types
        JCExpression expr = transformExpression(term, BoxingStrategy.UNBOXED, expectedType, EXPR_WIDEN_PRIM);
        // unary + is essentially a NOOP
        if (operator == OperatorTranslation.UNARY_POSITIVE)
            return expr;
        ret = make().Unary(operator.javacOperator, expr);
        ret = unAutoPromote(ret, op.getTypeModel());
    } else {
        if (operator == OperatorTranslation.UNARY_POSITIVE) {
            // is the self type of Invertible, so use the type of op
            return transformExpression(term, BoxingStrategy.BOXED, op.getTypeModel());
        }
        ret = make().Apply(null, makeSelect(transformExpression(term, BoxingStrategy.BOXED, expectedType), Naming.getGetterName(operator.ceylonMethod)), List.<JCExpression>nil());
    }
    return ret;
}
Also used : JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) Term(com.redhat.ceylon.compiler.typechecker.tree.Tree.Term) JCTree(com.sun.tools.javac.tree.JCTree) Tree(com.redhat.ceylon.compiler.typechecker.tree.Tree) AssignmentOperatorTranslation(com.redhat.ceylon.compiler.java.codegen.Operators.AssignmentOperatorTranslation) OperatorTranslation(com.redhat.ceylon.compiler.java.codegen.Operators.OperatorTranslation)

Example 3 with Term

use of com.redhat.ceylon.compiler.typechecker.tree.Tree.Term in project ceylon-compiler by ceylon.

the class StatementTransformer method spanOpIteration.

/**
 * Returns a {@link SpanOpIterationOptimization} if that optimization applies
 * to the given {@code for} statement, otherwise null.
 * @param stmt The for statement
 * @return a {@link SpanOpIterationOptimization} or null.
 */
private ForStatementTransformation spanOpIteration(Tree.ForStatement stmt) {
    if (isOptimizationDisabled(stmt, Optimization.SpanOpIteration)) {
        return optimizationFailed(stmt, Optimization.SpanOpIteration, "optimization explicitly disabled by @disableOptimization");
    }
    Tree.ForIterator iterator = stmt.getForClause().getForIterator();
    if (!(iterator instanceof Tree.ValueIterator)) {
        return optimizationFailed(stmt, Optimization.SpanOpIteration, "optimization applies only to ValueIterators");
    }
    Tree.ValueIterator vi = (Tree.ValueIterator) iterator;
    Tree.SpecifierExpression specifier = vi.getSpecifierExpression();
    Tree.Term term = specifier.getExpression().getTerm();
    final Tree.Term increment;
    final Tree.RangeOp range;
    if (term instanceof Tree.RangeOp) {
        // So it's a for (i in (lhs..rhs)) { ... }
        increment = null;
        range = (Tree.RangeOp) term;
    } else if (term instanceof Tree.InvocationExpression) {
        Tree.InvocationExpression inv = (Tree.InvocationExpression) term;
        if (inv.getPrimary() instanceof Tree.QualifiedMemberExpression) {
            Tree.QualifiedMemberExpression prim = (Tree.QualifiedMemberExpression) inv.getPrimary();
            if ("by".equals(prim.getIdentifier().getText()) && prim.getPrimary() instanceof Tree.Expression && (((Tree.Expression) (prim.getPrimary())).getTerm() instanceof Tree.RangeOp)) {
                // So it's a for (i in (lhs..rhs).by(increment)) { ... }
                range = (Tree.RangeOp) ((Tree.Expression) (prim.getPrimary())).getTerm();
                if (inv.getPositionalArgumentList() != null) {
                    Tree.PositionalArgument a = inv.getPositionalArgumentList().getPositionalArguments().get(0);
                    if (a instanceof Tree.ListedArgument)
                        increment = ((Tree.ListedArgument) a).getExpression().getTerm();
                    else
                        return optimizationFailed(stmt, Optimization.SpanOpIteration, "Unable to determine expression for argument to by(): appears spread or comprehension");
                } else if (inv.getNamedArgumentList() != null) {
                    Tree.SpecifiedArgument sarg = null;
                    for (Tree.NamedArgument arg : inv.getNamedArgumentList().getNamedArguments()) {
                        if ("step".equals(arg.getIdentifier().getText())) {
                            if (arg instanceof Tree.SpecifiedArgument) {
                                sarg = ((Tree.SpecifiedArgument) arg);
                                break;
                            }
                        // TODO In theory we could support Tree.AttributeArgument too
                        }
                    }
                    if (sarg != null) {
                        increment = sarg.getSpecifierExpression().getExpression().getTerm();
                    } else {
                        return optimizationFailed(stmt, Optimization.SpanOpIteration, "Unable to determine expression for argument to by{}");
                    }
                } else {
                    return optimizationFailed(stmt, Optimization.SpanOpIteration, "Unable to get arguments to by()");
                }
            } else {
                return optimizationFailed(stmt, Optimization.SpanOpIteration, "Only applies to Iterables of the form 'lhs..rhs' or '(lhs..rhs).by(step)'");
            }
        } else {
            return optimizationFailed(stmt, Optimization.SpanOpIteration, "Only applies to Iterables of the form 'lhs..rhs' or '(lhs..rhs).by(step)'");
        }
    } else {
        return optimizationFailed(stmt, Optimization.SpanOpIteration, "Only applies to Iterables of the form 'lhs..rhs' or '(lhs..rhs).by(step)'");
    }
    com.sun.tools.javac.code.Type type;
    Type integerType = typeFact().getIntegerType();
    Type characterType = typeFact().getCharacterType();
    if (isSpanOf(range, integerType)) {
        type = syms().longType;
    } else if (isSpanOf(range, characterType)) {
        type = syms().intType;
    } else {
        return optimizationFailed(stmt, Optimization.SpanOpIteration, "The RangeOp doesn't produce a Range<Integer>/Range<Character>");
    }
    return increment == null ? new SpanOpIterationOptimization(stmt, range, increment, type) : new SpanOpWithStepIterationOptimization(stmt, range, increment, type);
}
Also used : Expression(com.redhat.ceylon.compiler.typechecker.tree.Tree.Expression) CustomTree(com.redhat.ceylon.compiler.typechecker.tree.CustomTree) JCTree(com.sun.tools.javac.tree.JCTree) Tree(com.redhat.ceylon.compiler.typechecker.tree.Tree) RangeOp(com.redhat.ceylon.compiler.typechecker.tree.Tree.RangeOp) Term(com.redhat.ceylon.compiler.typechecker.tree.Tree.Term) Type(com.redhat.ceylon.model.typechecker.model.Type) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) SpecifierOrInitializerExpression(com.redhat.ceylon.compiler.typechecker.tree.Tree.SpecifierOrInitializerExpression) Expression(com.redhat.ceylon.compiler.typechecker.tree.Tree.Expression) RangeOp(com.redhat.ceylon.compiler.typechecker.tree.Tree.RangeOp)

Example 4 with Term

use of com.redhat.ceylon.compiler.typechecker.tree.Tree.Term in project ceylon-compiler by ceylon.

the class ExpressionTransformer method transformExpression.

JCExpression transformExpression(final Tree.Term expr, BoxingStrategy boxingStrategy, Type expectedType, int flags) {
    if (expr == null) {
        return null;
    }
    at(expr);
    if (inStatement && boxingStrategy != BoxingStrategy.INDIFFERENT) {
        // We're not directly inside the ExpressionStatement anymore
        inStatement = false;
    }
    // Cope with things like ((expr))
    // FIXME: shouldn't that be in the visitor?
    Tree.Term term = expr;
    while (term instanceof Tree.Expression) {
        term = ((Tree.Expression) term).getTerm();
    }
    JCExpression result;
    if (term instanceof Tree.SequenceEnumeration) {
        // special case to be able to pass expected type to sequences
        result = transform((Tree.SequenceEnumeration) term, expectedType);
    } else if (term instanceof Tree.DefaultOp) {
        // special case to be able to pass expected type to else op
        result = transform((Tree.DefaultOp) term, expectedType);
    } else if (term instanceof Tree.LetExpression) {
        // special case to be able to pass expected type to let op
        result = transform((Tree.LetExpression) term, expectedType);
    } else if (term instanceof Tree.IfExpression) {
        // special case to be able to pass expected type to if op
        result = transform((Tree.IfExpression) term, expectedType);
    } else if (term instanceof Tree.SwitchExpression) {
        // special case to be able to pass expected type to switch op
        result = transform((Tree.SwitchExpression) term, expectedType);
    } else {
        CeylonVisitor v = gen().visitor;
        final ListBuffer<JCTree> prevDefs = v.defs;
        final boolean prevInInitializer = v.inInitializer;
        final ClassDefinitionBuilder prevClassBuilder = v.classBuilder;
        try {
            v.defs = new ListBuffer<JCTree>();
            v.inInitializer = false;
            v.classBuilder = gen().current();
            term.visit(v);
            if (v.hasResult()) {
                result = v.getSingleResult();
                if (result == null) {
                    throw new BugException(term, "visitor yielded multiple results");
                }
            } else {
                throw new BugException(term, "visitor didn't yield any result");
            }
        } catch (BugException e) {
            result = e.makeErroneous(this, expr);
        } finally {
            v.classBuilder = prevClassBuilder;
            v.inInitializer = prevInInitializer;
            v.defs = prevDefs;
        }
    }
    if ((flags & EXPR_TARGET_ACCEPTS_NULL) == 0 && expectedType != null && hasUncheckedNulls(expr) && expectedType.isSubtypeOf(typeFact().getObjectType())) {
        result = utilInvocation().checkNull(result);
        flags |= EXPR_HAS_NULL_CHECK_FENCE;
    }
    result = applyErasureAndBoxing(result, expr, boxingStrategy, expectedType, flags);
    return result;
}
Also used : Term(com.redhat.ceylon.compiler.typechecker.tree.Tree.Term) JCTree(com.sun.tools.javac.tree.JCTree) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) LetExpression(com.redhat.ceylon.compiler.typechecker.tree.Tree.LetExpression) Expression(com.redhat.ceylon.compiler.typechecker.tree.Tree.Expression) JCTree(com.sun.tools.javac.tree.JCTree) Tree(com.redhat.ceylon.compiler.typechecker.tree.Tree) LetExpression(com.redhat.ceylon.compiler.typechecker.tree.Tree.LetExpression)

Example 5 with Term

use of com.redhat.ceylon.compiler.typechecker.tree.Tree.Term in project ceylon-compiler by ceylon.

the class ExpressionTransformer method transformSpreadArgument.

private ExpressionAndType transformSpreadArgument(SimpleInvocation invocation, int numArguments, int argIndex, BoxingStrategy boxingStrategy, Type parameterType) {
    ExpressionAndType exprAndType;
    final Type iteratedType = typeFact().getIteratedType(parameterType);
    final JCExpression expr;
    final JCExpression type;
    // optimise "*javaArray.iterable" into "javaArray" for java variadic parameters, since we can pass them just along
    if (invocation.isJavaMethod() && numArguments == argIndex + 1 && !invocation.isArgumentComprehension(argIndex)) {
        Expression argumentExpression = invocation.getArgumentExpression(argIndex);
        Term argument = Decl.unwrapExpressionsUntilTerm(argumentExpression);
        if (argument instanceof Tree.QualifiedMemberExpression) {
            Tree.QualifiedMemberExpression qualifiedMemberArgument = (Tree.QualifiedMemberExpression) argument;
            if ("iterable".equals(qualifiedMemberArgument.getIdentifier().getText()) && isJavaArray(qualifiedMemberArgument.getPrimary().getTypeModel())) {
                // just pass the array as-is
                // we don't care at all about unboxing or casting since we can't be dealing with boxing
                // and we generate our own cast, at least for non-primitive arrays where it may be ambiguous,
                // we could avoid the cast for non-type-parameter and non-Object arrays, but that's more expensive
                // to check for
                JCExpression primary = transformExpression(qualifiedMemberArgument.getPrimary());
                type = makeJavaType(typeFact().getSequenceType(iteratedType).getType());
                if (isJavaObjectArray(qualifiedMemberArgument.getPrimary().getTypeModel())) {
                    expr = make().TypeCast(makeJavaType(qualifiedMemberArgument.getPrimary().getTypeModel()), primary);
                } else {
                    expr = primary;
                }
                return new ExpressionAndType(expr, type);
            }
        }
    }
    // invoking f(a, *b), where declared f(A a, B* b)
    // we can have several remaining arguments and the last one is spread
    List<JCExpression> x = List.<JCExpression>nil();
    for (int ii = argIndex; ii < numArguments; ii++) {
        JCExpression argExpr = invocation.getTransformedArgumentExpression(ii);
        // the last parameter is spread and must be put first
        if (ii < numArguments - 1) {
            x = x.append(argExpr);
        } else {
            // convert to a Sequential if required
            Type argType = invocation.getArgumentType(ii);
            if (!typeFact().isSequentialType(argType))
                argExpr = iterableToSequential(argExpr);
            x = x.prepend(argExpr);
        }
    }
    if (invocation.isJavaMethod()) {
        // collect all the initial arguments and wrap into a Java array
        // first arg is the spread part
        JCExpression last = x.head;
        // remove it from x
        x = x.tail;
        Type lastType = invocation.getArgumentType(numArguments - 1);
        // must translate it into a Util call
        expr = sequenceToJavaArray(invocation, last, parameterType, boxingStrategy, lastType, x);
    } else {
        JCExpression typeExpr = makeJavaType(iteratedType, JT_TYPE_ARGUMENT);
        JCExpression sequentialExpr = utilInvocation().sequentialInstance(typeExpr, makeReifiedTypeArgument(iteratedType), x.head, x.tail);
        if (invocation.isParameterVariadicPlus(argIndex)) {
            expr = utilInvocation().castSequentialToSequence(sequentialExpr, iteratedType);
        } else {
            expr = sequentialExpr;
        }
    }
    type = makeJavaType(typeFact().getSequenceType(iteratedType).getType());
    exprAndType = new ExpressionAndType(expr, type);
    return exprAndType;
}
Also used : Type(com.redhat.ceylon.model.typechecker.model.Type) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) LetExpression(com.redhat.ceylon.compiler.typechecker.tree.Tree.LetExpression) Expression(com.redhat.ceylon.compiler.typechecker.tree.Tree.Expression) JCTree(com.sun.tools.javac.tree.JCTree) Tree(com.redhat.ceylon.compiler.typechecker.tree.Tree) TreeUtil.unwrapExpressionUntilTerm(com.redhat.ceylon.compiler.typechecker.tree.TreeUtil.unwrapExpressionUntilTerm) Term(com.redhat.ceylon.compiler.typechecker.tree.Tree.Term)

Aggregations

Tree (com.redhat.ceylon.compiler.typechecker.tree.Tree)15 Term (com.redhat.ceylon.compiler.typechecker.tree.Tree.Term)15 JCTree (com.sun.tools.javac.tree.JCTree)12 JCExpression (com.sun.tools.javac.tree.JCTree.JCExpression)9 Expression (com.redhat.ceylon.compiler.typechecker.tree.Tree.Expression)5 Type (com.redhat.ceylon.model.typechecker.model.Type)5 TreeUtil.unwrapExpressionUntilTerm (com.redhat.ceylon.compiler.typechecker.tree.TreeUtil.unwrapExpressionUntilTerm)4 AssignmentOperatorTranslation (com.redhat.ceylon.compiler.java.codegen.Operators.AssignmentOperatorTranslation)3 OperatorTranslation (com.redhat.ceylon.compiler.java.codegen.Operators.OperatorTranslation)3 CustomTree (com.redhat.ceylon.compiler.typechecker.tree.CustomTree)3 SpecifierOrInitializerExpression (com.redhat.ceylon.compiler.typechecker.tree.Tree.SpecifierOrInitializerExpression)3 Declaration (com.redhat.ceylon.model.typechecker.model.Declaration)3 TypeDeclaration (com.redhat.ceylon.model.typechecker.model.TypeDeclaration)3 SyntheticName (com.redhat.ceylon.compiler.java.codegen.Naming.SyntheticName)2 OptimisationStrategy (com.redhat.ceylon.compiler.java.codegen.Operators.OptimisationStrategy)2 LetExpression (com.redhat.ceylon.compiler.typechecker.tree.Tree.LetExpression)2 ClassOrInterface (com.redhat.ceylon.model.typechecker.model.ClassOrInterface)2 Function (com.redhat.ceylon.model.typechecker.model.Function)2 Interface (com.redhat.ceylon.model.typechecker.model.Interface)2 TypedDeclaration (com.redhat.ceylon.model.typechecker.model.TypedDeclaration)2