Search in sources :

Example 81 with ClassOrInterface

use of org.eclipse.ceylon.model.typechecker.model.ClassOrInterface in project ceylon by eclipse.

the class ClassTransformer method addAtMembers.

private void addAtMembers(ClassDefinitionBuilder classBuilder, ClassOrInterface model, Tree.ClassOrInterface def) {
    List<JCExpression> members = List.nil();
    for (Declaration member : model.getMembers()) {
        if (member instanceof ClassOrInterface == false && member instanceof TypeAlias == false) {
            continue;
        }
        TypeDeclaration innerType = (TypeDeclaration) member;
        Tree.Declaration innerTypeTree = findInnerType(def, innerType.getName());
        if (innerTypeTree != null) {
            TransformationPlan plan = errors().hasDeclarationAndMarkBrokenness(innerTypeTree);
            if (plan instanceof Drop) {
                continue;
            }
        }
        if (innerType.isAlias() && innerTypeTree != null && Decl.isAncestorLocal(innerTypeTree.getDeclarationModel()))
            // for the same reason we do not generate aliases in transform(ClassOrInterface def) let's not list them
            continue;
        JCAnnotation atMember;
        // interfaces are moved to toplevel so they can lose visibility of member types if they are local
        if (Decl.isLocal(model) && model instanceof Interface)
            atMember = makeAtMember(innerType.getName());
        else
            atMember = makeAtMember(innerType.getType());
        members = members.prepend(atMember);
    }
    classBuilder.annotations(makeAtMembers(members));
}
Also used : ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) JCExpression(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression) JCPrimitiveTypeTree(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCPrimitiveTypeTree) JCTree(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) TypeAlias(org.eclipse.ceylon.model.typechecker.model.TypeAlias) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) MethodDeclaration(org.eclipse.ceylon.compiler.typechecker.tree.Tree.MethodDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) TransformationPlan(org.eclipse.ceylon.compiler.java.codegen.recovery.TransformationPlan) JCAnnotation(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCAnnotation) Interface(org.eclipse.ceylon.model.typechecker.model.Interface) ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) LazyInterface(org.eclipse.ceylon.model.loader.model.LazyInterface) Drop(org.eclipse.ceylon.compiler.java.codegen.recovery.Drop)

Example 82 with ClassOrInterface

use of org.eclipse.ceylon.model.typechecker.model.ClassOrInterface in project ceylon by eclipse.

the class CeylonVisitor method visit.

public void visit(Tree.ExtendedType extendedType) {
    ClassOrInterface forDefinition = classBuilder.getForDefinition();
    Type thisType = forDefinition != null ? forDefinition.getType() : null;
    Type extended = extendedType.getType().getTypeModel();
    if (extended.isConstructor()) {
        extended = extended.getQualifyingType();
    }
    classBuilder.extending(thisType, extended);
    gen.expressionGen().transformSuperInvocation(extendedType, classBuilder);
}
Also used : ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) Type(org.eclipse.ceylon.model.typechecker.model.Type)

Example 83 with ClassOrInterface

use of org.eclipse.ceylon.model.typechecker.model.ClassOrInterface in project ceylon by eclipse.

the class ExpressionTransformer method transform.

public JCExpression transform(Tree.IndexExpression indexedExpr) {
    // depends on the operator
    Tree.ElementOrRange elementOrRange = indexedExpr.getElementOrRange();
    if (elementOrRange instanceof Tree.Element) {
        // foo[index] -- foo could be a Correspondence, Java List or Java Map
        final AbstractIndexTransformer transformer;
        final Type primaryType = indexedExpr.getPrimary().getTypeModel().resolveAliases();
        Type leftType = primaryType.getSupertype(typeFact().getCorrespondenceDeclaration());
        if (leftType != null) {
            Type rightType = getTypeArgument(leftType, 0);
            transformer = new CorrespondenceIndexTransformer(indexedExpr, leftType, rightType, getTypeArgument(leftType, 1));
        } else {
            leftType = primaryType.getSupertype(typeFact().getJavaListDeclaration());
            if (leftType != null) {
                Type rightType = typeFact().getIntegerType();
                if (rightType.isCached()) {
                    rightType = rightType.clone();
                }
                rightType.setUnderlyingType("int");
                transformer = new JavaListIndexTransformer(indexedExpr, leftType, rightType, getTypeArgument(leftType, 0));
            } else {
                leftType = primaryType.getSupertype(typeFact().getJavaMapDeclaration());
                if (leftType != null) {
                    Type rightType = getTypeArgument(leftType, 0);
                    transformer = new JavaMapIndexTransformer(indexedExpr, leftType, rightType, getTypeArgument(leftType, 1));
                } else if (isJavaArray(primaryType)) {
                    Type rightType = typeFact().getIntegerType();
                    if (rightType.isCached()) {
                        rightType = rightType.clone();
                    }
                    rightType.setUnderlyingType("int");
                    Type elementType;
                    if (isJavaObjectArray(primaryType)) {
                        leftType = primaryType.getSupertype(typeFact().getJavaObjectArrayDeclaration());
                        elementType = getTypeArgument(leftType, 0);
                    } else if (JvmBackendUtil.isJavaBooleanArray(primaryType.getDeclaration())) {
                        leftType = typeFact().getJavaBooleanArrayDeclaration().getType();
                        elementType = typeFact().getBooleanType();
                    } else if (JvmBackendUtil.isJavaByteArray(primaryType.getDeclaration())) {
                        leftType = typeFact().getJavaByteArrayDeclaration().getType();
                        elementType = typeFact().getByteType();
                    } else if (JvmBackendUtil.isJavaShortArray(primaryType.getDeclaration())) {
                        leftType = typeFact().getJavaShortArrayDeclaration().getType();
                        elementType = typeFact().getIntegerType();
                    } else if (JvmBackendUtil.isJavaIntArray(primaryType.getDeclaration())) {
                        leftType = typeFact().getJavaIntArrayDeclaration().getType();
                        elementType = typeFact().getIntegerType();
                    } else if (JvmBackendUtil.isJavaLongArray(primaryType.getDeclaration())) {
                        leftType = typeFact().getJavaLongArrayDeclaration().getType();
                        elementType = typeFact().getIntegerType();
                    } else if (JvmBackendUtil.isJavaFloatArray(primaryType.getDeclaration())) {
                        leftType = typeFact().getJavaFloatArrayDeclaration().getType();
                        elementType = typeFact().getFloatType();
                    } else if (JvmBackendUtil.isJavaDoubleArray(primaryType.getDeclaration())) {
                        leftType = typeFact().getJavaDoubleArrayDeclaration().getType();
                        elementType = typeFact().getFloatType();
                    } else if (JvmBackendUtil.isJavaCharArray(primaryType.getDeclaration())) {
                        leftType = typeFact().getJavaCharArrayDeclaration().getType();
                        elementType = typeFact().getCharacterType();
                    } else {
                        return makeErroneous(indexedExpr, "Unsupported primary for indexed expression");
                    }
                    transformer = new JavaArrayIndexTransformer(indexedExpr, leftType, rightType, elementType);
                } else {
                    return makeErroneous(indexedExpr, "Unsupported primary for indexed expression");
                }
            }
        }
        return transformer.transform(indexedExpr);
    } else {
        // foo[start:end] or foo[start:length]
        Type primaryType = indexedExpr.getPrimary().getTypeModel();
        Type leftType = primaryType.getSupertype(typeFact().getRangedDeclaration());
        Type rightType = getTypeArgument(leftType, 0);
        Tree.ElementRange range = (Tree.ElementRange) indexedExpr.getElementOrRange();
        // do the indices
        JCExpression start = transformExpression(range.getLowerBound(), BoxingStrategy.BOXED, rightType);
        // is this a span or segment?
        String method;
        final List<JCExpression> args;
        if (range.getLowerBound() != null && range.getLength() != null) {
            method = "measure";
            JCExpression length = transformExpression(range.getLength(), BoxingStrategy.UNBOXED, typeFact().getIntegerType());
            args = List.of(start, length);
        } else if (range.getLowerBound() == null) {
            method = "spanTo";
            JCExpression end = transformExpression(range.getUpperBound(), BoxingStrategy.BOXED, rightType);
            args = List.of(end);
        } else if (range.getUpperBound() == null) {
            method = "spanFrom";
            args = List.of(start);
        } else if (range.getLowerBound() != null && range.getUpperBound() != null) {
            method = "span";
            JCExpression end = transformExpression(range.getUpperBound(), BoxingStrategy.BOXED, rightType);
            args = List.of(start, end);
        } else {
            method = "unknown";
            args = List.<JCExpression>of(makeErroneous(range, "compiler bug: unhandled range"));
        }
        JCExpression lhs;
        Tree.Primary primary = indexedExpr.getPrimary();
        boolean isSuper = isSuper(primary);
        if (isSuper || isSuperOf(primary)) {
            Declaration member = primaryType.getDeclaration().getMember(method, null, false);
            TypeDeclaration leftDeclaration = (TypeDeclaration) member.getContainer();
            if (isSuper)
                lhs = transformSuper(indexedExpr, leftDeclaration);
            else
                lhs = transformSuperOf(indexedExpr, indexedExpr.getPrimary(), method);
        } else {
            int flags = 0;
            // See https://github.com/ceylon/ceylon/issues/6365
            if (leftType.getDeclaration() instanceof ClassOrInterface && // even more disgusting: https://github.com/ceylon/ceylon/issues/6450
            !isCeylonString(primaryType) && hasConstrainedTypeParameters(leftType.getDeclaration().getType()))
                flags |= EXPR_EXPECTED_TYPE_HAS_CONSTRAINED_TYPE_PARAMETERS;
            lhs = transformExpression(indexedExpr.getPrimary(), BoxingStrategy.BOXED, leftType, flags);
        }
        JCExpression result;
        // Because tuple open span access has the type of the indexed element
        // (not a sequential of the union of types in the ranged) a typecast may be required.
        Type rangedSpanType = getTypeArgument(leftType, 2);
        Type expectedType = indexedExpr.getTypeModel();
        int flags = 0;
        if (!expectedType.isExactly(rangedSpanType)) {
            flags |= EXPR_DOWN_CAST;
            // make sure we barf properly if we missed a heuristics
            if (method.equals("spanFrom")) {
                // make a "Util.<method>(lhs, start, end)" call
                at(indexedExpr);
                result = utilInvocation().tuple_spanFrom(args.prepend(lhs));
            } else {
                result = makeErroneous(indexedExpr, "compiler bug: only the spanFrom method should be specialised for Tuples");
            }
        } else {
            // make a "lhs.<method>(start, end)" call
            result = at(indexedExpr).Apply(List.<JCTree.JCExpression>nil(), makeSelect(lhs, method), args);
        }
        result = applyErasureAndBoxing(result, rangedSpanType, CodegenUtil.hasTypeErased(indexedExpr), true, BoxingStrategy.BOXED, expectedType, flags);
        return result;
    }
}
Also used : ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) OutputElement(org.eclipse.ceylon.model.loader.model.OutputElement) 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) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)

Example 84 with ClassOrInterface

use of org.eclipse.ceylon.model.typechecker.model.ClassOrInterface in project ceylon by eclipse.

the class ExpressionTransformer method makeTypeParameterDeclaration.

/**
 * Makes an expression equivalent to the result of {@code `given T`}
 * @param node
 * @param declaration
 * @return
 */
JCExpression makeTypeParameterDeclaration(Node node, TypeParameter declaration) {
    Scope container = declaration.getContainer();
    if (container instanceof Declaration) {
        JCExpression containerExpr;
        Declaration containerDeclaration = (Declaration) container;
        if (containerDeclaration instanceof ClassOrInterface || containerDeclaration instanceof TypeAlias) {
            JCExpression metamodelCall = makeTypeDeclarationLiteral((TypeDeclaration) containerDeclaration);
            JCExpression metamodelCast = makeJavaType(typeFact().getLanguageModuleDeclarationTypeDeclaration("GenericDeclaration").getType(), JT_NO_PRIMITIVES);
            containerExpr = make().TypeCast(metamodelCast, metamodelCall);
        } else if (containerDeclaration.isToplevel()) {
            containerExpr = makeTopLevelValueOrFunctionDeclarationLiteral(containerDeclaration);
        } else {
            containerExpr = makeMemberValueOrFunctionDeclarationLiteral(node, containerDeclaration);
        }
        // now it must be a ClassOrInterfaceDeclaration or a FunctionDeclaration, both of which have the method we need
        return at(node).Apply(null, makeSelect(containerExpr, "getTypeParameterDeclaration"), List.of(ceylonLiteral(declaration.getName())));
    } else {
        return makeErroneous(node, "compiler bug: " + container + " is not a supported type parameter container");
    }
}
Also used : ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) JCExpression(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression) Scope(org.eclipse.ceylon.model.typechecker.model.Scope) TypeAlias(org.eclipse.ceylon.model.typechecker.model.TypeAlias) 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 85 with ClassOrInterface

use of org.eclipse.ceylon.model.typechecker.model.ClassOrInterface in project ceylon by eclipse.

the class InterfaceVisitor method visit.

@Override
public void visit(Tree.ClassOrInterface that) {
    ClassOrInterface model = that.getDeclarationModel();
    // and they are useless at runtime
    if (!model.isAlias()) {
        // we never need to collect other local declaration names since only interfaces compete in the $impl name range
        if (model instanceof Interface)
            collect(that, (Interface) model);
        Set<String> old = localCompanionClasses;
        localCompanionClasses = new HashSet<String>();
        super.visit(that);
        localCompanionClasses = old;
    }
    if (model instanceof Interface) {
        ((Interface) model).setCompanionClassNeeded(isInterfaceWithCode(model));
    }
}
Also used : ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) Interface(org.eclipse.ceylon.model.typechecker.model.Interface)

Aggregations

ClassOrInterface (org.eclipse.ceylon.model.typechecker.model.ClassOrInterface)102 TypeDeclaration (org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)62 Declaration (org.eclipse.ceylon.model.typechecker.model.Declaration)48 TypedDeclaration (org.eclipse.ceylon.model.typechecker.model.TypedDeclaration)46 Type (org.eclipse.ceylon.model.typechecker.model.Type)44 Tree (org.eclipse.ceylon.compiler.typechecker.tree.Tree)27 Class (org.eclipse.ceylon.model.typechecker.model.Class)24 Interface (org.eclipse.ceylon.model.typechecker.model.Interface)23 Scope (org.eclipse.ceylon.model.typechecker.model.Scope)23 TypeParameter (org.eclipse.ceylon.model.typechecker.model.TypeParameter)20 ModelUtil.getContainingClassOrInterface (org.eclipse.ceylon.model.typechecker.model.ModelUtil.getContainingClassOrInterface)19 Value (org.eclipse.ceylon.model.typechecker.model.Value)19 ModelUtil.appliedType (org.eclipse.ceylon.model.typechecker.model.ModelUtil.appliedType)18 ArrayList (java.util.ArrayList)17 FunctionOrValue (org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)17 Constructor (org.eclipse.ceylon.model.typechecker.model.Constructor)16 Function (org.eclipse.ceylon.model.typechecker.model.Function)14 LazyInterface (org.eclipse.ceylon.model.loader.model.LazyInterface)13 JCExpression (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression)12 UnknownType (org.eclipse.ceylon.model.typechecker.model.UnknownType)12