Search in sources :

Example 16 with SyntheticName

use of com.redhat.ceylon.compiler.java.codegen.Naming.SyntheticName in project ceylon-compiler by ceylon.

the class ExpressionTransformer method transform.

public JCExpression transform(Tree.ScaleOp op) {
    OperatorTranslation operator = Operators.getOperator(Tree.ScaleOp.class);
    Tree.Term scalableTerm = op.getRightTerm();
    Type scalableTermType = getSupertype(scalableTerm, typeFact().getScalableDeclaration());
    SyntheticName scaleableName = naming.alias("scalable");
    JCVariableDecl scaleable = makeVar(scaleableName, makeJavaType(scalableTermType, JT_NO_PRIMITIVES), transformExpression(scalableTerm, BoxingStrategy.BOXED, scalableTermType));
    Tree.Term scaleTerm = op.getLeftTerm();
    SyntheticName scaleName = naming.alias("scale");
    Type scaleType = getTypeArgument(scalableTermType, 0);
    JCExpression scaleValue;
    if (isCeylonInteger(scaleTerm.getTypeModel()) && isCeylonFloat(scaleType)) {
        // Disgusting coercion
        scaleValue = transformExpression(scaleTerm, BoxingStrategy.UNBOXED, scalableTerm.getTypeModel());
        scaleValue = boxType(scaleValue, typeFact().getFloatType());
    } else {
        scaleValue = transformExpression(scaleTerm, BoxingStrategy.BOXED, scaleType);
    }
    JCVariableDecl scale = makeVar(scaleName, makeJavaType(scaleType, JT_NO_PRIMITIVES), scaleValue);
    at(op);
    return make().LetExpr(List.<JCStatement>of(scale, scaleable), transformOverridableBinaryOperator(operator, OptimisationStrategy.NONE, scaleableName.makeIdent(), scaleName.makeIdent(), null, null, op.getTypeModel()));
}
Also used : Type(com.redhat.ceylon.model.typechecker.model.Type) 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) SyntheticName(com.redhat.ceylon.compiler.java.codegen.Naming.SyntheticName) 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)

Example 17 with SyntheticName

use of com.redhat.ceylon.compiler.java.codegen.Naming.SyntheticName in project ceylon-compiler by ceylon.

the class ExpressionTransformer method makeOptimizedInIntegerOrCharacterMeasure.

protected JCTree makeOptimizedInIntegerOrCharacterMeasure(Tree.InOp op, com.sun.tools.javac.code.Type ceylonType, com.sun.tools.javac.code.Type javaType) {
    Tree.SegmentOp rangeOp = (Tree.SegmentOp) op.getRightTerm();
    SyntheticName xName = naming.temp("x");
    SyntheticName yName = naming.temp("y");
    SyntheticName zName = naming.temp("z");
    SyntheticName wName = naming.temp("w");
    JCExpression x = transformExpression(op.getLeftTerm(), BoxingStrategy.UNBOXED, typeFact().getObjectType());
    JCExpression y = transformExpression(rangeOp.getLeftTerm(), BoxingStrategy.UNBOXED, rangeOp.getLeftTerm().getTypeModel());
    JCExpression z = transformExpression(rangeOp.getRightTerm(), BoxingStrategy.UNBOXED, rangeOp.getRightTerm().getTypeModel());
    JCExpression w = make().Apply(null, naming.makeSelect(make().QualIdent(ceylonType.tsym), "offset"), List.<JCExpression>of(xName.makeIdent(), yName.makeIdent()));
    return make().LetExpr(List.<JCStatement>of(makeVar(xName, make().Type(javaType), x), makeVar(yName, make().Type(javaType), y), makeVar(zName, make().Type(syms().longType), z), makeVar(wName, make().Type(syms().longType), w)), make().Binary(JCTree.AND, make().Binary(JCTree.GT, zName.makeIdent(), make().Literal(0L)), make().Binary(JCTree.AND, make().Binary(JCTree.LE, make().Literal(0L), wName.makeIdent()), make().Binary(JCTree.LT, wName.makeIdent(), zName.makeIdent()))));
}
Also used : JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) JCTree(com.sun.tools.javac.tree.JCTree) Tree(com.redhat.ceylon.compiler.typechecker.tree.Tree) SyntheticName(com.redhat.ceylon.compiler.java.codegen.Naming.SyntheticName)

Example 18 with SyntheticName

use of com.redhat.ceylon.compiler.java.codegen.Naming.SyntheticName in project ceylon-compiler by ceylon.

the class ExpressionTransformer method makeOptimizedInIntegerRange.

protected JCTree makeOptimizedInIntegerRange(Tree.InOp op, com.sun.tools.javac.code.Type type) {
    // x in y..z with x, y, z all Integer
    com.sun.tools.javac.code.Type ceylonType = syms().ceylonIntegerType;
    Tree.RangeOp rangeOp = (Tree.RangeOp) op.getRightTerm();
    JCExpression x = transformExpression(op.getLeftTerm(), BoxingStrategy.UNBOXED, typeFact().getObjectType());
    JCExpression first = transformExpression(rangeOp.getLeftTerm(), BoxingStrategy.UNBOXED, rangeOp.getLeftTerm().getTypeModel());
    JCExpression last = transformExpression(rangeOp.getRightTerm(), BoxingStrategy.UNBOXED, rangeOp.getRightTerm().getTypeModel());
    SyntheticName xName = naming.temp("x");
    SyntheticName firstName = naming.temp("y");
    SyntheticName lastName = naming.temp("z");
    SyntheticName recursiveName = naming.temp("recursive");
    return make().LetExpr(List.<JCStatement>of(makeVar(xName, make().Type(type), x), makeVar(firstName, make().Type(type), first), makeVar(lastName, make().Type(type), last), makeVar(recursiveName, make().Type(syms().booleanType), make().Binary(JCTree.AND, make().Binary(JCTree.GT, firstName.makeIdent(), make().Binary(JCTree.PLUS, firstName.makeIdent(), make().Literal(1L))), make().Binary(JCTree.GT, make().Binary(JCTree.MINUS, lastName.makeIdent(), make().Literal(1L)), lastName.makeIdent())))), make().Conditional(recursiveName.makeIdent(), // x.offset(first) <= last.offset(first)
    make().Binary(JCTree.LE, make().Apply(null, naming.makeSelect(make().QualIdent(ceylonType.tsym), "offset"), List.<JCExpression>of(xName.makeIdent(), firstName.makeIdent())), make().Apply(null, naming.makeSelect(make().QualIdent(ceylonType.tsym), "offset"), List.<JCExpression>of(lastName.makeIdent(), firstName.makeIdent()))), make().Binary(JCTree.OR, make().Binary(JCTree.AND, make().Binary(JCTree.LE, firstName.makeIdent(), xName.makeIdent()), make().Binary(JCTree.LE, xName.makeIdent(), lastName.makeIdent())), make().Binary(JCTree.AND, make().Binary(JCTree.LE, lastName.makeIdent(), xName.makeIdent()), make().Binary(JCTree.LE, xName.makeIdent(), firstName.makeIdent())))));
}
Also used : JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) JCTree(com.sun.tools.javac.tree.JCTree) Tree(com.redhat.ceylon.compiler.typechecker.tree.Tree) SyntheticName(com.redhat.ceylon.compiler.java.codegen.Naming.SyntheticName)

Example 19 with SyntheticName

use of com.redhat.ceylon.compiler.java.codegen.Naming.SyntheticName in project ceylon-compiler by ceylon.

the class ExpressionTransformer method transformSpreadTupleArgument.

private List<ExpressionAndType> transformSpreadTupleArgument(SimpleInvocation invocation, CallBuilder callBuilder, List<ExpressionAndType> result, final int argIndex) {
    BoxingStrategy boxingStrategy;
    // Spread tuple Argument
    // invoking f(*args), where declared f(A a, B a) (last param not sequenced)
    final Tree.Expression tupleArgument = invocation.getArgumentExpression(argIndex);
    final int minimumTupleArguments = typeFact().getTupleMinimumLength(tupleArgument.getTypeModel());
    final boolean tupleUnbounded = typeFact().isTupleLengthUnbounded(tupleArgument.getTypeModel());
    final Type callableType = invocation.getPrimary().getTypeModel().getFullType();
    // Only evaluate the tuple expr once
    SyntheticName tupleAlias = naming.alias("tuple");
    JCExpression tupleType;
    JCExpression tupleExpr = transformExpression(tupleArgument, BoxingStrategy.BOXED, null);
    tupleType = makeJavaType(typeFact().getSequentialDeclaration().getType(), JT_RAW);
    tupleExpr = make().TypeCast(makeJavaType(typeFact().getSequentialDeclaration().getType(), JT_RAW), tupleExpr);
    callBuilder.appendStatement(makeVar(tupleAlias, tupleType, tupleExpr));
    if (callBuilder.getArgumentHandling() == 0) {
        // XXX Hack: Only do this if we're not already doing 
        // something funky with arguments e.g. SpreadOp
        callBuilder.argumentHandling(CallBuilder.CB_LET, naming.alias("spreadarg"));
    }
    callBuilder.voidMethod(invocation.getReturnType() == null || Decl.isUnboxedVoid(invocation.getPrimaryDeclaration()) || isWithinSuperInvocation());
    /* Cases:
            *[] -> () => nothing
            *[] -> (Integer=) => nothing
            *[] -> (Integer*) => nothing
            *[Integer] -> (Integer) => extract
            *[Integer] -> (Integer=) => extract
            *[Integer] -> (Integer*) => pass the tuple as-is
            *[Integer*] -> (Integer*) => pass the tuple as-is
            *[Integer+] -> (Integer*) => pass the tuple as-is
            *[Integer] -> (Integer, Integer*) => extract and drop the tuple
            *[Integer,Integer] -> (Integer, Integer) => extract
            *[Integer,Integer] -> (Integer=, Integer=) => extract
            *[Integer,Integer] -> (Integer, Integer*) => extract and pass the tuple rest
            *[Integer,Integer*] -> (Integer, Integer*) => extract and pass the tuple rest
            *[Integer,Integer+] -> (Integer, Integer*) => extract and pass the tuple rest
        */
    int spreadArgIndex = argIndex;
    final int maxParameters = getNumParametersOfCallable(callableType);
    boolean variadic = maxParameters > 0 && invocation.isParameterSequenced(maxParameters - 1);
    // we extract from the tuple not more than we have tuple members, but even less than that if we don't
    // have enough parameters to put them in
    final int argumentsToExtract = Math.min(argIndex + minimumTupleArguments, variadic ? maxParameters - 1 : maxParameters);
    for (; spreadArgIndex < argumentsToExtract; spreadArgIndex++) {
        boxingStrategy = invocation.getParameterBoxingStrategy(spreadArgIndex);
        Type paramType = getParameterTypeOfCallable(callableType, spreadArgIndex);
        JCExpression tupleIndex = boxType(make().Literal((long) spreadArgIndex - argIndex), typeFact().getIntegerType());
        JCExpression tupleElement = make().Apply(null, naming.makeQualIdent(tupleAlias.makeIdent(), "get"), List.<JCExpression>of(tupleIndex));
        tupleElement = applyErasureAndBoxing(tupleElement, typeFact().getAnythingType(), true, boxingStrategy, paramType);
        JCExpression argType = makeJavaType(paramType, boxingStrategy == BoxingStrategy.BOXED ? JT_NO_PRIMITIVES : 0);
        result = result.append(new ExpressionAndType(tupleElement, argType));
    }
    // - OR the tuple is bounded but we did not pass them all
    if (variadic && (tupleUnbounded || argumentsToExtract < (minimumTupleArguments + argIndex))) {
        boxingStrategy = invocation.getParameterBoxingStrategy(spreadArgIndex);
        Type paramType = getParameterTypeOfCallable(callableType, spreadArgIndex);
        JCExpression tupleElement = tupleAlias.makeIdent();
        // argIndex = 0, tuple = [Integer+], params = [Integer, Integer*], spreadArgIndex = 1 => spanFrom(1)
        if (spreadArgIndex - argIndex > 0) {
            JCExpression tupleIndex = boxType(make().Literal((long) spreadArgIndex - argIndex), typeFact().getIntegerType());
            tupleElement = make().Apply(null, naming.makeQualIdent(tupleElement, "spanFrom"), List.<JCExpression>of(tupleIndex));
        }
        tupleElement = applyErasureAndBoxing(tupleElement, typeFact().getAnythingDeclaration().getType(), true, boxingStrategy, paramType);
        JCExpression argType = makeJavaType(paramType, boxingStrategy == BoxingStrategy.BOXED ? JT_NO_PRIMITIVES : 0);
        JCExpression expr;
        if (invocation.isJavaMethod()) {
            // no need to handle leading arguments since that is handled by transformSpreadArgument
            // if ever we have leading arguments we never end up in this method
            expr = sequenceToJavaArray(invocation, tupleElement, paramType, boxingStrategy, paramType, List.<JCExpression>nil());
        } else {
            expr = tupleElement;
        }
        result = result.append(new ExpressionAndType(expr, argType));
    } else if (variadic && invocation.isIndirect() && argumentsToExtract >= minimumTupleArguments && !tupleUnbounded) {
        result = result.append(new ExpressionAndType(makeEmptyAsSequential(true), makeJavaType(typeFact().getSequenceType(typeFact().getAnythingDeclaration().getType()), JT_RAW)));
    }
    return result;
}
Also used : Type(com.redhat.ceylon.model.typechecker.model.Type) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) Expression(com.redhat.ceylon.compiler.typechecker.tree.Tree.Expression) JCTree(com.sun.tools.javac.tree.JCTree) Tree(com.redhat.ceylon.compiler.typechecker.tree.Tree) SyntheticName(com.redhat.ceylon.compiler.java.codegen.Naming.SyntheticName)

Aggregations

SyntheticName (com.redhat.ceylon.compiler.java.codegen.Naming.SyntheticName)19 JCExpression (com.sun.tools.javac.tree.JCTree.JCExpression)19 Tree (com.redhat.ceylon.compiler.typechecker.tree.Tree)9 JCTree (com.sun.tools.javac.tree.JCTree)9 Type (com.redhat.ceylon.model.typechecker.model.Type)8 JCStatement (com.sun.tools.javac.tree.JCTree.JCStatement)8 Value (com.redhat.ceylon.model.typechecker.model.Value)5 AttributeDeclaration (com.redhat.ceylon.compiler.typechecker.tree.Tree.AttributeDeclaration)4 MethodDeclaration (com.redhat.ceylon.compiler.typechecker.tree.Tree.MethodDeclaration)4 Declaration (com.redhat.ceylon.model.typechecker.model.Declaration)4 TypeDeclaration (com.redhat.ceylon.model.typechecker.model.TypeDeclaration)4 TypedDeclaration (com.redhat.ceylon.model.typechecker.model.TypedDeclaration)4 JavaBeanValue (com.redhat.ceylon.model.loader.model.JavaBeanValue)3 FunctionOrValue (com.redhat.ceylon.model.typechecker.model.FunctionOrValue)3 JCVariableDecl (com.sun.tools.javac.tree.JCTree.JCVariableDecl)3 AssignmentOperatorTranslation (com.redhat.ceylon.compiler.java.codegen.Operators.AssignmentOperatorTranslation)2 OperatorTranslation (com.redhat.ceylon.compiler.java.codegen.Operators.OperatorTranslation)2 CustomTree (com.redhat.ceylon.compiler.typechecker.tree.CustomTree)2 Expression (com.redhat.ceylon.compiler.typechecker.tree.Tree.Expression)2 Term (com.redhat.ceylon.compiler.typechecker.tree.Tree.Term)2