Search in sources :

Example 81 with JCExpression

use of com.sun.tools.javac.tree.JCTree.JCExpression in project ceylon-compiler by ceylon.

the class ExpressionTransformer method makeMemberValueOrFunctionDeclarationLiteral.

JCExpression makeMemberValueOrFunctionDeclarationLiteral(Node node, Declaration declaration, boolean f) {
    // it's a member we get from its container declaration
    if (declaration.getContainer() instanceof ClassOrInterface == false)
        return makeErroneous(node, "compiler bug: " + declaration.getContainer() + " is not a supported type parameter container");
    ClassOrInterface container = (ClassOrInterface) declaration.getContainer();
    // use the generated class to get to the declaration literal
    JCExpression metamodelCall = makeTypeDeclarationLiteral(container);
    JCExpression metamodelCast = makeJavaType(typeFact().getLanguageModuleDeclarationTypeDeclaration(Decl.isConstructor(declaration) ? "ClassDeclaration" : "ClassOrInterfaceDeclaration").getType(), JT_NO_PRIMITIVES);
    metamodelCall = make().TypeCast(metamodelCast, metamodelCall);
    String memberClassName;
    String memberAccessor;
    if (declaration instanceof Class)
        memberClassName = "ClassDeclaration";
    else if (Decl.isConstructor(declaration))
        memberClassName = "ConstructorDeclaration";
    else if (declaration instanceof Interface)
        memberClassName = "InterfaceDeclaration";
    else if (declaration instanceof Function)
        memberClassName = "FunctionDeclaration";
    else if (declaration instanceof Value) {
        memberClassName = "ValueDeclaration";
    } else {
        return makeErroneous(node, "compiler bug: " + declaration + " is not a supported declaration literal");
    }
    if (Decl.isConstructor(declaration))
        memberAccessor = "getConstructorDeclaration";
    else
        memberAccessor = f ? "getMemberDeclaration" : "getDeclaredMemberDeclaration";
    TypeDeclaration metamodelDecl = (TypeDeclaration) typeFact().getLanguageModuleDeclarationDeclaration(memberClassName);
    JCExpression memberType = makeJavaType(metamodelDecl.getType());
    JCExpression reifiedMemberType = makeReifiedTypeArgument(metamodelDecl.getType());
    JCExpression memberCall = make().Apply(List.of(memberType), makeSelect(metamodelCall, memberAccessor), List.of(reifiedMemberType, ceylonLiteral(declaration.getName())));
    return memberCall;
}
Also used : ClassOrInterface(com.redhat.ceylon.model.typechecker.model.ClassOrInterface) Function(com.redhat.ceylon.model.typechecker.model.Function) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) FunctionOrValue(com.redhat.ceylon.model.typechecker.model.FunctionOrValue) FieldValue(com.redhat.ceylon.model.loader.model.FieldValue) Value(com.redhat.ceylon.model.typechecker.model.Value) Class(com.redhat.ceylon.model.typechecker.model.Class) JCNewClass(com.sun.tools.javac.tree.JCTree.JCNewClass) TypeDeclaration(com.redhat.ceylon.model.typechecker.model.TypeDeclaration) Interface(com.redhat.ceylon.model.typechecker.model.Interface) ClassOrInterface(com.redhat.ceylon.model.typechecker.model.ClassOrInterface)

Example 82 with JCExpression

use of com.sun.tools.javac.tree.JCTree.JCExpression in project ceylon-compiler by ceylon.

the class ExpressionTransformer method transformOverridableBinaryOperator.

private JCExpression transformOverridableBinaryOperator(OperatorTranslation originalOperator, OptimisationStrategy optimisationStrategy, JCExpression left, JCExpression right, Tree.Term leftTerm, Type leftType, Tree.Term rightTerm, Type expectedType) {
    JCExpression result = null;
    // optimise if we can
    if (optimisationStrategy.useJavaOperator()) {
        result = make().Binary(originalOperator.javacOperator, left, right);
        if (rightTerm != null) {
            result = unAutoPromote(result, expectedType);
        }
        return result;
    }
    boolean loseComparison = originalOperator == OperatorTranslation.BINARY_SMALLER || originalOperator == OperatorTranslation.BINARY_SMALL_AS || originalOperator == OperatorTranslation.BINARY_LARGER || originalOperator == OperatorTranslation.BINARY_LARGE_AS;
    // for comparisons we need to invoke compare()
    OperatorTranslation actualOperator = originalOperator;
    if (loseComparison) {
        actualOperator = Operators.OperatorTranslation.BINARY_COMPARE;
    }
    List<JCExpression> args = List.of(right);
    List<JCExpression> typeArgs = null;
    // Set operators need reified generics
    if (originalOperator == OperatorTranslation.BINARY_UNION || originalOperator == OperatorTranslation.BINARY_INTERSECTION || originalOperator == OperatorTranslation.BINARY_COMPLEMENT) {
        Type otherSetElementType = typeFact().getIteratedType(rightTerm.getTypeModel());
        args = args.prepend(makeReifiedTypeArgument(otherSetElementType));
        typeArgs = List.<JCExpression>of(makeJavaType(otherSetElementType, JT_TYPE_ARGUMENT));
    }
    if (optimisationStrategy.useValueTypeMethod()) {
        int flags = JT_NO_PRIMITIVES;
        if (optimisationStrategy == OptimisationStrategy.OPTIMISE_VALUE_TYPE && leftType.getDeclaration().getSelfType() != null) {
            leftType = leftType.getTypeArguments().get(leftType.getDeclaration().getSelfType().getDeclaration());
        }
        result = make().Apply(typeArgs, naming.makeQualIdent(makeJavaType(leftType, flags), actualOperator.ceylonMethod), args.prepend(left));
    } else {
        if ((originalOperator == OperatorTranslation.BINARY_LARGE_AS || originalOperator == OperatorTranslation.BINARY_LARGER || originalOperator == OperatorTranslation.BINARY_SMALL_AS || originalOperator == OperatorTranslation.BINARY_SMALLER || originalOperator == OperatorTranslation.BINARY_COMPARE) && willEraseToObject(leftType)) {
            left = make().TypeCast(makeJavaType(typeFact().getComparableDeclaration().getType(), JT_RAW), left);
            args = List.<JCExpression>of(make().TypeCast(makeJavaType(typeFact().getComparableDeclaration().getType(), JT_RAW), right));
        }
        result = make().Apply(typeArgs, makeSelect(left, actualOperator.ceylonMethod), args);
    }
    if (loseComparison) {
        // We cheat slightly bu using == instead of equals, but since those values
        // don't override equals the effect is the same
        result = make().Binary(originalOperator.javacValueOperator, result, makeLanguageValue(originalOperator.ceylonValue));
    }
    return result;
}
Also used : Type(com.redhat.ceylon.model.typechecker.model.Type) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) AssignmentOperatorTranslation(com.redhat.ceylon.compiler.java.codegen.Operators.AssignmentOperatorTranslation) OperatorTranslation(com.redhat.ceylon.compiler.java.codegen.Operators.OperatorTranslation)

Example 83 with JCExpression

use of com.sun.tools.javac.tree.JCTree.JCExpression in project ceylon-compiler by ceylon.

the class ExpressionTransformer method transformBaseInstantiation.

private JCExpression transformBaseInstantiation(Invocation invocation, CallBuilder callBuilder, TransformedInvocationPrimary transformedPrimary) {
    JCExpression resultExpr;
    Tree.BaseTypeExpression type = (Tree.BaseTypeExpression) invocation.getPrimary();
    Declaration declaration = type.getDeclaration();
    invocation.location(callBuilder);
    if (Strategy.generateInstantiator(declaration)) {
        resultExpr = callBuilder.typeArguments(List.<JCExpression>nil()).invoke(naming.makeInstantiatorMethodName(transformedPrimary.expr, (Class) declaration)).build();
        if (Strategy.isInstantiatorUntyped(declaration)) {
            // $new method declared to return Object, so needs typecast
            resultExpr = make().TypeCast(makeJavaType(((TypeDeclaration) declaration).getType()), resultExpr);
        }
    } else {
        Type classType = (Type) type.getTarget();
        if (isJavaArray(classType)) {
            JCExpression typeExpr = makeJavaType(classType, AbstractTransformer.JT_CLASS_NEW | AbstractTransformer.JT_RAW);
            callBuilder.javaArrayInstance(typeExpr);
            if (isJavaObjectArray(classType)) {
                Type elementType = classType.getTypeArgumentList().get(0);
                MultidimensionalArray multiArray = getMultiDimensionalArrayInfo(elementType);
                if (multiArray != null)
                    elementType = multiArray.type;
                // array of Foo is fine, array of Nothing too
                if (elementType.getDeclaration() instanceof ClassOrInterface || elementType.isNothing()) {
                    if (!elementType.getTypeArgumentList().isEmpty())
                        callBuilder.javaArrayInstanceNeedsCast(makeJavaType(classType, AbstractTransformer.JT_NO_PRIMITIVES));
                } else {
                    // if it's an array of union, intersection or type param we need a runtime allocation
                    callBuilder.javaArrayInstanceIsGeneric(makeReifiedTypeArgument(elementType), multiArray != null ? multiArray.dimension + 1 : 1);
                }
            }
        } else {
            if (Decl.isConstructor(classType.getDeclaration())) {
                classType = classType.getExtendedType();
            }
            JCExpression typeExpr = makeJavaType(classType, AbstractTransformer.JT_CLASS_NEW);
            callBuilder.instantiate(typeExpr);
        }
        resultExpr = callBuilder.build();
    }
    return resultExpr;
}
Also used : ClassOrInterface(com.redhat.ceylon.model.typechecker.model.ClassOrInterface) 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) Class(com.redhat.ceylon.model.typechecker.model.Class) JCNewClass(com.sun.tools.javac.tree.JCTree.JCNewClass) TypedDeclaration(com.redhat.ceylon.model.typechecker.model.TypedDeclaration) Declaration(com.redhat.ceylon.model.typechecker.model.Declaration) TypeDeclaration(com.redhat.ceylon.model.typechecker.model.TypeDeclaration)

Example 84 with JCExpression

use of com.sun.tools.javac.tree.JCTree.JCExpression in project ceylon-compiler by ceylon.

the class ExpressionTransformer method transform.

public JCTree transform(Tree.ObjectExpression expr) {
    at(expr);
    List<JCTree> klass = classGen().transformObjectExpression(expr);
    at(expr);
    JCExpression newCall = make().NewClass(null, null, makeUnquotedIdent(naming.escapeClassName(expr.getAnonymousClass().getName()) + "_"), List.<JCTree.JCExpression>nil(), null);
    return make().LetExpr((List) klass, newCall);
}
Also used : JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) JCTree(com.sun.tools.javac.tree.JCTree)

Example 85 with JCExpression

use of com.sun.tools.javac.tree.JCTree.JCExpression in project ceylon-compiler by ceylon.

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);
    final Type returnType = getMostPreciseType(term, getTypeArgument(valueType, 0));
    // we work on boxed types unless we could have optimised
    return transformAssignAndReturnOperation(expr, term, !canOptimise, valueType, 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.PLUS : JCTree.MINUS, previousValue, makeInteger(1));
                ret = unAutoPromote(ret, returnType);
                return ret;
            }
            // make this call: previousValue.getSuccessor() or previousValue.getPredecessor()
            return make().Apply(null, makeSelect(previousValue, operator.ceylonMethod), List.<JCExpression>nil());
        }
    });
}
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) 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) AssignmentOperatorTranslation(com.redhat.ceylon.compiler.java.codegen.Operators.AssignmentOperatorTranslation) OperatorTranslation(com.redhat.ceylon.compiler.java.codegen.Operators.OperatorTranslation)

Aggregations

JCExpression (com.sun.tools.javac.tree.JCTree.JCExpression)311 JCTree (com.sun.tools.javac.tree.JCTree)95 Type (com.redhat.ceylon.model.typechecker.model.Type)85 JCStatement (com.sun.tools.javac.tree.JCTree.JCStatement)81 Tree (com.redhat.ceylon.compiler.typechecker.tree.Tree)67 JCVariableDecl (com.sun.tools.javac.tree.JCTree.JCVariableDecl)59 ListBuffer (com.sun.tools.javac.util.ListBuffer)54 JCTypeParameter (com.sun.tools.javac.tree.JCTree.JCTypeParameter)39 Name (com.sun.tools.javac.util.Name)39 SyntheticName (com.redhat.ceylon.compiler.java.codegen.Naming.SyntheticName)37 TypeDeclaration (com.redhat.ceylon.model.typechecker.model.TypeDeclaration)35 TypedDeclaration (com.redhat.ceylon.model.typechecker.model.TypedDeclaration)34 JCBlock (com.sun.tools.javac.tree.JCTree.JCBlock)34 JavacTreeMaker (lombok.javac.JavacTreeMaker)33 JCAnnotation (com.sun.tools.javac.tree.JCTree.JCAnnotation)30 TypeParameter (com.redhat.ceylon.model.typechecker.model.TypeParameter)29 Declaration (com.redhat.ceylon.model.typechecker.model.Declaration)27 Function (com.redhat.ceylon.model.typechecker.model.Function)26 Parameter (com.redhat.ceylon.model.typechecker.model.Parameter)26 JCNewClass (com.sun.tools.javac.tree.JCTree.JCNewClass)26