Search in sources :

Example 86 with Interface

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

the class ExpressionTransformer method lostTypeParameterInInheritance.

private boolean lostTypeParameterInInheritance(ClassOrInterface exprDecl, ClassOrInterface commonDecl, boolean searchInterfaces, boolean lostTypeParameter) {
    // stop if we found the common decl
    if (Decl.equal(exprDecl, commonDecl))
        return lostTypeParameter;
    if (searchInterfaces) {
        // find a match in interfaces
        for (Type pt : exprDecl.getSatisfiedTypes()) {
            // FIXME: this is very heavy-handed because we consider that once we've lost a type parameter we've lost them all
            // but we could optimise this by checking:
            // 1/ which type parameter we've really lost
            // 2/ if the type parameters we're passing to our super type actually depend in any way from type parameters we've lost
            boolean lostTypeParameter2 = lostTypeParameter || isTurnedToRaw(pt);
            pt = simplifyType(pt);
            // skip unknown types
            if (pt.isUnknown())
                continue;
            // it has to be an interface
            Interface interf = (Interface) pt.getDeclaration();
            if (lostTypeParameterInInheritance(interf, commonDecl, searchInterfaces, lostTypeParameter2))
                return true;
        }
    }
    // search for super classes
    Type extendedType = exprDecl.getExtendedType();
    if (extendedType != null) {
        // FIXME: see above
        boolean lostTypeParameter2 = lostTypeParameter || isTurnedToRaw(extendedType);
        extendedType = simplifyType(extendedType);
        // it has to be a Class
        Class extendedTypeDeclaration = (Class) extendedType.getDeclaration();
        // looks like Object's superclass is Object, so stop right there
        if (extendedTypeDeclaration != typeFact().getObjectDeclaration())
            return lostTypeParameterInInheritance(extendedTypeDeclaration, commonDecl, searchInterfaces, lostTypeParameter2);
    }
    // didn't find it
    return false;
}
Also used : UnionType(org.eclipse.ceylon.model.typechecker.model.UnionType) Type(org.eclipse.ceylon.model.typechecker.model.Type) JCNewClass(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCNewClass) Class(org.eclipse.ceylon.model.typechecker.model.Class) Interface(org.eclipse.ceylon.model.typechecker.model.Interface) ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) LazyInterface(org.eclipse.ceylon.model.loader.model.LazyInterface)

Example 87 with Interface

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

the class ExpressionTransformer method transformQualifiedInstantiation.

private JCExpression transformQualifiedInstantiation(Invocation invocation, CallBuilder callBuilder, TransformedInvocationPrimary transformedPrimary) {
    Tree.QualifiedTypeExpression qte = (Tree.QualifiedTypeExpression) invocation.getPrimary();
    Declaration declaration = qte.getDeclaration();
    invocation.location(callBuilder);
    if (Decl.isJavaStaticOrInterfacePrimary(invocation.getPrimary())) {
        callBuilder.instantiate(transformedPrimary.expr);
    } else if (!Strategy.generateInstantiator(declaration)) {
        if (Decl.isConstructorPrimary(invocation.getPrimary())) {
            if (ModelUtil.getConstructedClass(invocation.getPrimaryDeclaration()).isMember()) /*&& invocation.getPrimary() instanceof Tree.QualifiedTypeExpression
                        && !(((Tree.QualifiedTypeExpression)invocation.getPrimary()).getPrimary() instanceof Tree.BaseTypeExpression)*/
            {
                callBuilder.instantiate(new ExpressionAndType(transformedPrimary.expr, null), makeJavaType(invocation.getReturnType(), JT_CLASS_NEW | (transformedPrimary.expr == null ? 0 : JT_NON_QUALIFIED)));
            } else {
                callBuilder.instantiate(makeJavaType(invocation.getReturnType(), JT_CLASS_NEW));
            }
        } else {
            JCExpression qualifier;
            JCExpression qualifierType;
            if (declaration.getContainer() instanceof Interface) {
                // When doing qualified invocation through an interface we need
                // to get the companion.
                Interface qualifyingInterface = (Interface) declaration.getContainer();
                qualifier = transformedPrimary.expr;
                qualifierType = makeJavaType(qualifyingInterface.getType(), JT_COMPANION);
            } else {
                qualifier = transformedPrimary.expr;
                if (declaration.getContainer() instanceof TypeDeclaration) {
                    qualifierType = makeJavaType(((TypeDeclaration) declaration.getContainer()).getType());
                } else {
                    qualifierType = null;
                }
            }
            Type classType = (Type) qte.getTarget();
            JCExpression type;
            // special case for package-qualified things that are not really qualified
            if (qualifier == null) {
                type = makeJavaType(classType, AbstractTransformer.JT_CLASS_NEW);
            } else {
                // Note: here we're not fully qualifying the class name because the JLS says that if "new" is qualified the class name
                // is qualified relative to it
                type = makeJavaType(classType, AbstractTransformer.JT_CLASS_NEW | AbstractTransformer.JT_NON_QUALIFIED);
            }
            callBuilder.instantiate(new ExpressionAndType(qualifier, qualifierType), type);
        }
    } else {
        // instantiator
        callBuilder.typeArguments(List.<JCExpression>nil());
        java.util.List<Type> typeModels = qte.getTypeArguments().getTypeModels();
        if (typeModels != null) {
            for (Type tm : typeModels) {
                callBuilder.typeArgument(makeJavaType(tm, AbstractTransformer.JT_TYPE_ARGUMENT));
            }
        }
        callBuilder.invoke(naming.makeInstantiatorMethodName(transformedPrimary.expr, ModelUtil.getConstructedClass(declaration)));
    }
    JCExpression result = callBuilder.build();
    if (Strategy.isInstantiatorUntyped(declaration)) {
        result = make().TypeCast(makeJavaType(invocation.getReturnType()), result);
    }
    return result;
}
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) CondList(org.eclipse.ceylon.compiler.java.codegen.StatementTransformer.CondList) List(org.eclipse.ceylon.langtools.tools.javac.util.List) ParameterList(org.eclipse.ceylon.model.typechecker.model.ParameterList) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) 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) Interface(org.eclipse.ceylon.model.typechecker.model.Interface) ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) LazyInterface(org.eclipse.ceylon.model.loader.model.LazyInterface)

Example 88 with Interface

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

the class ExpressionTransformer method transform.

// 
// Operator-Assignment expressions
public JCExpression transform(final Tree.ArithmeticAssignmentOp op) {
    final AssignmentOperatorTranslation operator = Operators.getAssignmentOperator(op.getClass());
    if (operator == null) {
        return makeErroneous(op, "compiler bug: " + op.getNodeType() + " is not a supported arithmetic assignment operator");
    }
    // see if we can optimise it
    if (op.getUnboxed() && CodegenUtil.isDirectAccessVariable(op.getLeftTerm())) {
        return optimiseAssignmentOperator(op, operator);
    }
    // we can use unboxed types if both operands are unboxed
    final boolean boxResult = !op.getUnboxed();
    // find the proper type
    Interface compoundType = op.getUnit().getNumericDeclaration();
    if (op instanceof Tree.AddAssignOp) {
        compoundType = op.getUnit().getSummableDeclaration();
    } else if (op instanceof Tree.SubtractAssignOp) {
        compoundType = op.getUnit().getInvertableDeclaration();
    } else if (op instanceof Tree.RemainderAssignOp) {
        compoundType = op.getUnit().getIntegralDeclaration();
    }
    final Type leftType = getSupertype(op.getLeftTerm(), compoundType);
    // Normally we don't look at the RHS type because it can lead to unknown types, but if we want to extract its
    // underlying type we have to, and we deal with any eventual unknown type. Presumably unknown types will not have
    // any useful underlying type anyways.
    // Note  that looking at the RHS allows us to not have the issue of using the LHS type wrongly for the RHS type when
    // the LHS type is Float and the RHS type is Integer with implicit Float coercion
    Type rightSupertype = getSupertype(op.getRightTerm(), compoundType);
    if (rightSupertype == null || rightSupertype.isUnknown()) {
        // supertype could be null if, e.g. right type is Nothing
        rightSupertype = leftType;
    }
    Type rightTypeArgument = getTypeArgument(rightSupertype);
    if (rightTypeArgument == null || rightTypeArgument.isUnknown())
        rightTypeArgument = getTypeArgument(leftType);
    final Type rightType = getMostPreciseType(op.getLeftTerm(), rightTypeArgument);
    final Type resultType = getLeastPreciseType(op.getLeftTerm(), op.getRightTerm());
    // we work on boxed types
    return transformAssignAndReturnOperation(op, op.getLeftTerm(), boxResult, op.getLeftTerm().getTypeModel(), resultType, new AssignAndReturnOperationFactory() {

        @Override
        public JCExpression getNewValue(JCExpression previousValue) {
            // make this call: previousValue OP RHS
            JCExpression ret = transformOverridableBinaryOperator(op, op.getLeftTerm(), op.getRightTerm(), rightType, operator.binaryOperator, boxResult ? OptimisationStrategy.NONE : OptimisationStrategy.OPTIMISE, previousValue, op.getTypeModel());
            return ret;
        }
    });
}
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) AssignmentOperatorTranslation(org.eclipse.ceylon.compiler.java.codegen.Operators.AssignmentOperatorTranslation) JCTree(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) Interface(org.eclipse.ceylon.model.typechecker.model.Interface) ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) LazyInterface(org.eclipse.ceylon.model.loader.model.LazyInterface)

Example 89 with Interface

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

the class ClassTransformer method walkSatisfiedInterfacesInternal.

private void walkSatisfiedInterfacesInternal(final Class model, Type type, Class via, SatisfactionVisitor visitor, Set<Interface> satisfiedInterfaces) {
    type = type.resolveAliases();
    Type ext = type.getExtendedType();
    if (ext != null) {
        // recurse up this extended class
        walkSatisfiedInterfacesInternal(model, ext, (Class) ext.getDeclaration(), visitor, satisfiedInterfaces);
    }
    for (Type sat : type.getSatisfiedTypes()) {
        if (sat.isIdentifiable()) {
            return;
        }
        Interface iface = (Interface) sat.getDeclaration();
        // recurse up this satisfies interface
        walkSatisfiedInterfacesInternal(model, sat, via, visitor, satisfiedInterfaces);
        boolean alreadySatisfied = !satisfiedInterfaces.add((Interface) model.getType().getSupertype(iface).getDeclaration());
        if (via != null) {
            visitor.satisfiesIndirectlyViaClass(model, iface, via, alreadySatisfied);
        } else if (model.getType().equals(type)) {
            visitor.satisfiesDirectly(model, iface, alreadySatisfied);
        } else {
            visitor.satisfiesIndirectly(model, iface, alreadySatisfied);
        }
    }
}
Also used : Type(org.eclipse.ceylon.model.typechecker.model.Type) Interface(org.eclipse.ceylon.model.typechecker.model.Interface) ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) LazyInterface(org.eclipse.ceylon.model.loader.model.LazyInterface)

Example 90 with Interface

use of org.eclipse.ceylon.model.typechecker.model.Interface 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)

Aggregations

Interface (org.eclipse.ceylon.model.typechecker.model.Interface)105 ClassOrInterface (org.eclipse.ceylon.model.typechecker.model.ClassOrInterface)99 Type (org.eclipse.ceylon.model.typechecker.model.Type)64 TypeDeclaration (org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)58 Tree (org.eclipse.ceylon.compiler.typechecker.tree.Tree)40 Declaration (org.eclipse.ceylon.model.typechecker.model.Declaration)35 LazyInterface (org.eclipse.ceylon.model.loader.model.LazyInterface)34 Class (org.eclipse.ceylon.model.typechecker.model.Class)32 ModelUtil.getContainingClassOrInterface (org.eclipse.ceylon.model.typechecker.model.ModelUtil.getContainingClassOrInterface)32 TypedDeclaration (org.eclipse.ceylon.model.typechecker.model.TypedDeclaration)32 UnknownType (org.eclipse.ceylon.model.typechecker.model.UnknownType)29 ModelUtil.appliedType (org.eclipse.ceylon.model.typechecker.model.ModelUtil.appliedType)27 TypeParameter (org.eclipse.ceylon.model.typechecker.model.TypeParameter)21 ModelUtil.getOuterClassOrInterface (org.eclipse.ceylon.model.typechecker.model.ModelUtil.getOuterClassOrInterface)20 UnionType (org.eclipse.ceylon.model.typechecker.model.UnionType)20 ModelUtil.intersectionType (org.eclipse.ceylon.model.typechecker.model.ModelUtil.intersectionType)19 ModelUtil.unionType (org.eclipse.ceylon.model.typechecker.model.ModelUtil.unionType)19 AnalyzerUtil.getTupleType (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTupleType)18 AnalyzerUtil.spreadType (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.spreadType)18 JCTree (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree)18