Search in sources :

Example 66 with Type

use of com.redhat.ceylon.model.typechecker.model.Type in project ceylon-compiler by ceylon.

the class AbstractTransformer method nonWideningType.

Type nonWideningType(TypedReference declaration, TypedReference refinedDeclaration) {
    final Reference pr;
    if (declaration.equals(refinedDeclaration)) {
        pr = declaration;
    } else {
        Type refinedType = refinedDeclaration.getType();
        // since it may have changed name
        if (refinedType.getDeclaration() instanceof TypeParameter && refinedType.getDeclaration().getContainer() instanceof Function) {
            // find its index in the refined declaration
            TypeParameter refinedTypeParameter = (TypeParameter) refinedType.getDeclaration();
            Function refinedMethod = (Function) refinedTypeParameter.getContainer();
            int i = 0;
            for (TypeParameter tp : refinedMethod.getTypeParameters()) {
                if (tp.getName().equals(refinedTypeParameter.getName()))
                    break;
                i++;
            }
            if (i >= refinedMethod.getTypeParameters().size()) {
                throw new BugException("can't find type parameter " + refinedTypeParameter.getName() + " in its container " + refinedMethod.getName());
            }
            // the refining method type parameter should be at the same index
            if (declaration.getDeclaration() instanceof Function == false)
                throw new BugException("refining declaration is not a method: " + declaration);
            Function refiningMethod = (Function) declaration.getDeclaration();
            if (i >= refiningMethod.getTypeParameters().size()) {
                throw new BugException("refining method does not have enough type parameters to refine " + refinedMethod.getName());
            }
            pr = refiningMethod.getTypeParameters().get(i).getType();
        } else {
            pr = refinedType;
        }
    }
    if (pr.getDeclaration() instanceof Functional && Decl.isMpl((Functional) pr.getDeclaration())) {
        // the innermost Callable.
        return getReturnTypeOfCallable(pr.getFullType());
    }
    return pr.getType();
}
Also used : Functional(com.redhat.ceylon.model.typechecker.model.Functional) Function(com.redhat.ceylon.model.typechecker.model.Function) Type(com.redhat.ceylon.model.typechecker.model.Type) ModelUtil.appliedType(com.redhat.ceylon.model.typechecker.model.ModelUtil.appliedType) TypeParameter(com.redhat.ceylon.model.typechecker.model.TypeParameter) JCTypeParameter(com.sun.tools.javac.tree.JCTree.JCTypeParameter) Reference(com.redhat.ceylon.model.typechecker.model.Reference) TypedReference(com.redhat.ceylon.model.typechecker.model.TypedReference)

Example 67 with Type

use of com.redhat.ceylon.model.typechecker.model.Type in project ceylon-compiler by ceylon.

the class AbstractTransformer method getJavaArrayElementType.

private JCExpression getJavaArrayElementType(Type type, int flags) {
    if (type == null)
        return makeErroneous(null, "compiler bug: " + type + " is not a java array");
    type = simplifyType(type);
    if (type == null || type.getDeclaration() instanceof Class == false)
        return makeErroneous(null, "compiler bug: " + type + " is not a java array");
    Class c = (Class) type.getDeclaration();
    String name = c.getQualifiedNameString();
    if (name.equals("java.lang::ObjectArray")) {
        // fetch its type parameter
        if (type.getTypeArgumentList().size() != 1)
            return makeErroneous(null, "compiler bug: " + type + " is missing parameter type to java ObjectArray");
        Type elementType = type.getTypeArgumentList().get(0);
        if (elementType == null)
            return makeErroneous(null, "compiler bug: " + type + " has null parameter type to java ObjectArray");
        return make().TypeArray(makeJavaType(elementType, flags | JT_TYPE_ARGUMENT));
    } else if (name.equals("java.lang::ByteArray")) {
        return make().TypeArray(make().TypeIdent(TypeTags.BYTE));
    } else if (name.equals("java.lang::ShortArray")) {
        return make().TypeArray(make().TypeIdent(TypeTags.SHORT));
    } else if (name.equals("java.lang::IntArray")) {
        return make().TypeArray(make().TypeIdent(TypeTags.INT));
    } else if (name.equals("java.lang::LongArray")) {
        return make().TypeArray(make().TypeIdent(TypeTags.LONG));
    } else if (name.equals("java.lang::FloatArray")) {
        return make().TypeArray(make().TypeIdent(TypeTags.FLOAT));
    } else if (name.equals("java.lang::DoubleArray")) {
        return make().TypeArray(make().TypeIdent(TypeTags.DOUBLE));
    } else if (name.equals("java.lang::BooleanArray")) {
        return make().TypeArray(make().TypeIdent(TypeTags.BOOLEAN));
    } else if (name.equals("java.lang::CharArray")) {
        return make().TypeArray(make().TypeIdent(TypeTags.CHAR));
    } else {
        return makeErroneous(null, "compiler bug: " + type + " is an unknown java array type");
    }
}
Also used : Type(com.redhat.ceylon.model.typechecker.model.Type) ModelUtil.appliedType(com.redhat.ceylon.model.typechecker.model.ModelUtil.appliedType) Class(com.redhat.ceylon.model.typechecker.model.Class)

Example 68 with Type

use of com.redhat.ceylon.model.typechecker.model.Type in project ceylon-compiler by ceylon.

the class AbstractTransformer method isWideningTypeArguments.

private boolean isWideningTypeArguments(Type declType, Type refinedDeclType, boolean allowSubtypes) {
    if (declType == null || refinedDeclType == null)
        return false;
    // make sure we work on simplified types, to avoid stuff like optional or size-1 unions
    declType = simplifyType(declType);
    refinedDeclType = simplifyType(refinedDeclType);
    // special case for type parameters
    if (declType.getDeclaration() instanceof TypeParameter && refinedDeclType.getDeclaration() instanceof TypeParameter) {
        // consider them equivalent if they have the same bounds
        TypeParameter tp = (TypeParameter) declType.getDeclaration();
        TypeParameter refinedTP = (TypeParameter) refinedDeclType.getDeclaration();
        if (haveSameBounds(tp, refinedTP))
            return false;
        // if they don't have the same bounds and we don't allow subtypes then we're widening
        if (!allowSubtypes)
            return false;
        // if we allow subtypes, we're widening if tp is not a subtype of refinedTP
        return !tp.getType().isSubtypeOf(refinedTP.getType());
    }
    if (allowSubtypes) {
        if ((willEraseToObject(refinedDeclType))) {
            // - similarly if we both erase to object we're not widening
            return false;
        }
        // if we have exactly the same type don't bother finding a common ancestor
        if (!declType.isExactly(refinedDeclType)) {
            // check if we can form an informed decision
            if (refinedDeclType.getDeclaration() == null)
                return true;
            // find the instantiation of the refined decl type in the decl type
            // special case for optional types: let's find the definite type since
            // in java they are equivalent
            Type definiteType = typeFact().getDefiniteType(refinedDeclType);
            if (definiteType != null)
                refinedDeclType = definiteType;
            declType = declType.getSupertype(refinedDeclType.getDeclaration());
            // could not find common type, we must be widening somehow
            if (declType == null)
                return true;
        }
    }
    Map<TypeParameter, Type> typeArguments = declType.getTypeArguments();
    Map<TypeParameter, Type> refinedTypeArguments = refinedDeclType.getTypeArguments();
    java.util.List<TypeParameter> typeParameters = declType.getDeclaration().getTypeParameters();
    for (TypeParameter tp : typeParameters) {
        Type typeArgument = typeArguments.get(tp);
        if (typeArgument == null)
            // something fishy here
            return true;
        Type refinedTypeArgument = refinedTypeArguments.get(tp);
        if (refinedTypeArgument == null)
            // something fishy here
            return true;
        // check if the type arg is widening due to erasure
        if (isWidening(typeArgument, refinedTypeArgument))
            return true;
        // check if we are refining a covariant param which we must "fix" because it is dependend on, like Tuple's first TP
        if (declType.isCovariant(tp) && hasDependentTypeParameters(typeParameters, tp) && !typeArgument.isExactly(refinedTypeArgument) && // it is not widening if we refine Object with a TP, though
        !(willEraseToObject(refinedTypeArgument) && (isTypeParameter(typeArgument) || // it is also not widening if we erase both to Object
        willEraseToObject(typeArgument))))
            return true;
        // check if the type arg is a subtype, or if its type args are widening
        if (isWideningTypeArguments(typeArgument, refinedTypeArgument, tp.isCovariant()))
            return true;
    }
    // so far so good
    return false;
}
Also used : TypeParameter(com.redhat.ceylon.model.typechecker.model.TypeParameter) JCTypeParameter(com.sun.tools.javac.tree.JCTree.JCTypeParameter) Type(com.redhat.ceylon.model.typechecker.model.Type) ModelUtil.appliedType(com.redhat.ceylon.model.typechecker.model.ModelUtil.appliedType)

Example 69 with Type

use of com.redhat.ceylon.model.typechecker.model.Type in project ceylon-compiler by ceylon.

the class LinkRenderer method decorateWithLinkDropdownMenu.

private String decorateWithLinkDropdownMenu(String link, Type producedType) {
    if (!printLinkDropdownMenu || !printAbbreviated || !canLinkToCeylonLanguageModule()) {
        return link;
    }
    List<Type> producedTypes = new ArrayList<Type>();
    decompose(producedType, producedTypes);
    boolean containsOptional = false;
    boolean containsSequential = false;
    boolean containsSequence = false;
    boolean containsIterable = false;
    boolean containsEntry = false;
    boolean containsCallable = false;
    boolean containsTuple = false;
    for (Type pt : producedTypes) {
        if (abbreviateOptional(pt)) {
            containsOptional = true;
        } else if (abbreviateSequential(pt) && !link.contains("'Go to ceylon.language::Sequential'")) {
            containsSequential = true;
        } else if (abbreviateSequence(pt) && !link.contains("'Go to ceylon.language::Sequence'")) {
            containsSequence = true;
        } else if (abbreviateIterable(pt) && !link.contains("'Go to ceylon.language::Iterable'")) {
            containsIterable = true;
        } else if (abbreviateEntry(pt) && !link.contains("'Go to ceylon.language::Entry'")) {
            containsEntry = true;
        } else if (abbreviateCallable(pt) && !link.contains("'Go to ceylon.language::Callable'")) {
            containsCallable = true;
        } else if (abbreviateTuple(pt) && !link.contains("'Go to ceylon.language::Tuple'")) {
            containsTuple = true;
        }
    }
    Unit unit = producedType.getDeclaration().getUnit();
    if (containsOptional || containsSequential || containsSequence || containsIterable || containsEntry || containsCallable || containsTuple) {
        StringBuilder sb = new StringBuilder();
        sb.append("<span class='link-dropdown'>");
        sb.append(link.replaceAll("class='link'", "class='link type-identifier'"));
        sb.append("<span class='dropdown'>");
        sb.append("<a class='dropdown-toggle' data-toggle='dropdown' href='#'><b title='Show more links' class='caret'></b></a>");
        sb.append("<ul class='dropdown-menu'>");
        if (containsOptional) {
            sb.append(getLinkMenuItem(unit.getNullDeclaration(), "abbreviations X? means Null|X"));
        }
        if (containsSequential) {
            sb.append(getLinkMenuItem(unit.getSequentialDeclaration(), "abbreviation X[] or [X*] means Sequential&lt;X&gt;"));
        }
        if (containsSequence) {
            sb.append(getLinkMenuItem(unit.getSequenceDeclaration(), "abbreviation [X+] means Sequence&lt;X&gt;"));
        }
        if (containsIterable) {
            sb.append(getLinkMenuItem(unit.getIterableDeclaration(), "abbreviation {X+} or {X*} means Iterable&lt;X,Nothing&gt; or Iterable&lt;X,Null&gt;"));
        }
        if (containsEntry) {
            sb.append(getLinkMenuItem(unit.getEntryDeclaration(), "abbreviation X-&gt;Y means Entry&lt;X,Y&gt;"));
        }
        if (containsCallable) {
            sb.append(getLinkMenuItem(unit.getCallableDeclaration(), "abbreviation X(Y,Z) means Callable&lt;X,[Y,Z]&gt;"));
        }
        if (containsTuple) {
            sb.append(getLinkMenuItem(unit.getTupleDeclaration(), "abbreviation [X,Y] means Tuple&lt;X|Y,X,Tuple&lt;Y,Y,[]&gt;&gt;"));
        }
        // dropdown-menu
        sb.append("</ul>");
        // dropdown
        sb.append("</span>");
        // link-dropdown
        sb.append("</span>");
        return sb.toString();
    }
    return link;
}
Also used : Util.isAbbreviatedType(com.redhat.ceylon.ceylondoc.Util.isAbbreviatedType) NothingType(com.redhat.ceylon.model.typechecker.model.NothingType) Type(com.redhat.ceylon.model.typechecker.model.Type) ArrayList(java.util.ArrayList) Unit(com.redhat.ceylon.model.typechecker.model.Unit)

Example 70 with Type

use of com.redhat.ceylon.model.typechecker.model.Type in project ceylon-compiler by ceylon.

the class AbstractTransformer method makeOptimizedTypeTest.

JCExpression makeOptimizedTypeTest(JCExpression firstTimeExpr, Naming.CName varName, Type testedType, Type expressionType) {
    //TypeDeclaration widerDeclaration = expressionType.getDeclaration();
    if (!isTypeTestCheap(firstTimeExpr, varName, testedType, expressionType)) {
        //if (widerDeclaration instanceof UnionType
        //        || widerDeclaration instanceof ClassOrInterface) {
        // we've got a X|Y and we're testing for X
        // or parhaps a A|B|C|D and we're testing for C|D
        java.util.List<Type> cases = expressionType.getCaseTypes();
        if (cases != null) {
            java.util.List<Type> copiedCases = new ArrayList<>(cases.size());
            copiedCases.addAll(cases);
            cases = copiedCases;
            if ((testedType.isClassOrInterface() || testedType.isTypeParameter()) && cases.remove(testedType)) {
            } else if (testedType.isUnion()) {
                for (Type ct : testedType.getCaseTypes()) {
                    if (!cases.remove(ct)) {
                        cases = null;
                        break;
                    }
                }
            } else {
                cases = null;
            }
            if (cases != null) {
                Type complementType = typeFact().getNothingType();
                for (Type ct : cases) {
                    complementType = com.redhat.ceylon.model.typechecker.model.ModelUtil.unionType(complementType, ct, typeFact());
                }
                if (/*typeFact().getLanguageModuleDeclaration("Finished").equals(complementType.getDeclaration())
                                ||*/
                com.redhat.ceylon.model.typechecker.model.ModelUtil.intersectionType(complementType, testedType, typeFact()).isNothing()) {
                    return make().Unary(JCTree.NOT, makeTypeTest(firstTimeExpr, varName, complementType, expressionType));
                }
            }
        }
    //}
    }
    return makeTypeTest(firstTimeExpr, varName, testedType, expressionType);
}
Also used : Type(com.redhat.ceylon.model.typechecker.model.Type) ModelUtil.appliedType(com.redhat.ceylon.model.typechecker.model.ModelUtil.appliedType) ArrayList(java.util.ArrayList)

Aggregations

Type (com.redhat.ceylon.model.typechecker.model.Type)237 TypeDeclaration (com.redhat.ceylon.model.typechecker.model.TypeDeclaration)98 JCExpression (com.sun.tools.javac.tree.JCTree.JCExpression)87 TypeParameter (com.redhat.ceylon.model.typechecker.model.TypeParameter)56 JCTree (com.sun.tools.javac.tree.JCTree)53 Tree (com.redhat.ceylon.compiler.typechecker.tree.Tree)51 ModelUtil.appliedType (com.redhat.ceylon.model.typechecker.model.ModelUtil.appliedType)46 Class (com.redhat.ceylon.model.typechecker.model.Class)45 ClassOrInterface (com.redhat.ceylon.model.typechecker.model.ClassOrInterface)43 TypedDeclaration (com.redhat.ceylon.model.typechecker.model.TypedDeclaration)41 IntersectionType (com.redhat.ceylon.model.typechecker.model.IntersectionType)37 UnionType (com.redhat.ceylon.model.typechecker.model.UnionType)37 Test (org.junit.Test)37 TypeParser (com.redhat.ceylon.model.loader.TypeParser)36 Declaration (com.redhat.ceylon.model.typechecker.model.Declaration)34 Function (com.redhat.ceylon.model.typechecker.model.Function)33 Interface (com.redhat.ceylon.model.typechecker.model.Interface)30 JCTypeParameter (com.sun.tools.javac.tree.JCTree.JCTypeParameter)30 TypedReference (com.redhat.ceylon.model.typechecker.model.TypedReference)29 ArrayList (java.util.ArrayList)28