Search in sources :

Example 11 with Type

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

the class AbstractTransformer method getSimpleNumParametersOfCallable.

private int getSimpleNumParametersOfCallable(Type args) {
    // can be a defaulted tuple of Empty|Tuple
    if (args.isUnion()) {
        java.util.List<Type> caseTypes = args.getCaseTypes();
        if (caseTypes == null || caseTypes.size() != 2)
            return -1;
        Type caseA = caseTypes.get(0);
        TypeDeclaration caseADecl = caseA.getDeclaration();
        Type caseB = caseTypes.get(1);
        TypeDeclaration caseBDecl = caseB.getDeclaration();
        if (caseADecl instanceof ClassOrInterface == false || caseBDecl instanceof ClassOrInterface == false)
            return -1;
        if (caseADecl.getQualifiedNameString().equals("ceylon.language::Empty") && caseBDecl.getQualifiedNameString().equals("ceylon.language::Tuple"))
            return getSimpleNumParametersOfCallable(caseB);
        if (caseBDecl.getQualifiedNameString().equals("ceylon.language::Empty") && caseADecl.getQualifiedNameString().equals("ceylon.language::Tuple"))
            return getSimpleNumParametersOfCallable(caseA);
        return -1;
    }
    // can be Tuple, Empty, Sequence or Sequential
    if (!args.isClassOrInterface())
        return -1;
    TypeDeclaration declaration = args.getDeclaration();
    String name = declaration.getQualifiedNameString();
    if (name.equals("ceylon.language::Tuple")) {
        Type rest = args.getTypeArgumentList().get(2);
        int ret = getSimpleNumParametersOfCallable(rest);
        if (ret == -1)
            return -1;
        return ret + 1;
    }
    if (name.equals("ceylon.language::Empty")) {
        return 0;
    }
    if (name.equals("ceylon.language::Sequential") || name.equals("ceylon.language::Sequence")) {
        return 1;
    }
    return -1;
}
Also used : ClassOrInterface(com.redhat.ceylon.model.typechecker.model.ClassOrInterface) Type(com.redhat.ceylon.model.typechecker.model.Type) ModelUtil.appliedType(com.redhat.ceylon.model.typechecker.model.ModelUtil.appliedType) TypeDeclaration(com.redhat.ceylon.model.typechecker.model.TypeDeclaration)

Example 12 with Type

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

the class AbstractTransformer method rawSupertype.

/** 
     * Determine whether the given type, when appearing in 
     * an {@code extends} or {@code implements} clause, should be made raw.
     * This can happen because the type itself must be made raw, or because 
     * any of its supertypes were made raw.
     * See #1875.
     */
public boolean rawSupertype(Type ceylonType, int flags) {
    if (ceylonType == null || (flags & (JT_SATISFIES | JT_EXTENDS)) == 0) {
        return false;
    }
    Type simpleType = simplifyType(ceylonType);
    Map<TypeParameter, Type> tas = simpleType.getTypeArguments();
    java.util.List<TypeParameter> tps = simpleType.getDeclaration().getTypeParameters();
    for (TypeParameter tp : tps) {
        Type ta = tas.get(tp);
        // error handling
        if (ta == null)
            continue;
        // we want, so we make sure it's not Null
        if (isOptional(ta) && !isNull(ta)) {
            // For an optional type T?:
            // - The Ceylon type Foo<T?> results in the Java type Foo<T>.
            ta = getNonNullType(ta);
        }
        // In a type argument Foo<X&Object> or Foo<X?> transform to just Foo<X>
        ta = simplifyType(ta);
        if (typeFact().isUnion(ta) || typeFact().isIntersection(ta)) {
            // conform with where raw types would be used between expressions and constructors
            if (((flags & (JT_EXTENDS | JT_SATISFIES)) != 0 && tp.getSelfTypedDeclaration() != null)) {
                // A bit ugly, but we need to escape from the loop and create a raw type, no generics
                return true;
            } else if ((flags & (__JT_FULL_TYPE | JT_EXTENDS | JT_SATISFIES)) == 0) {
                return true;
            }
        // otherwise just go on
        }
        if (!tp.getSatisfiedTypes().isEmpty()) {
            boolean needsCastForBounds = false;
            for (Type bound : tp.getSatisfiedTypes()) {
                bound = bound.substitute(simpleType);
                needsCastForBounds |= expressionGen().needsCast(ta, bound, false, false, false);
            }
            if (needsCastForBounds) {
                // replace with the first bound
                ta = tp.getSatisfiedTypes().get(0).substitute(simpleType);
                if (tp.getSatisfiedTypes().size() > 1 || isBoundsSelfDependant(tp) || willEraseToObject(ta) || // we should reject it for all non-covariant types, unless we're in satisfies/extends
                ((flags & (JT_SATISFIES | JT_EXTENDS)) == 0 && !simpleType.isCovariant(tp))) {
                    // A bit ugly, but we need to escape from the loop and create a raw type, no generics
                    return true;
                }
            }
        }
        if (ta.isNothing() || // use the same erasure rules as bottom: prefer wildcards
        ((flags & (__JT_FULL_TYPE | JT_EXTENDS | JT_SATISFIES)) != 0 && (typeFact().isUnion(ta) || typeFact().isIntersection(ta)))) {
            // For the bottom type Bottom:
            if ((flags & (JT_CLASS_NEW)) != 0) {
                // A bit ugly, but we need to escape from the loop and create a raw type, no generics
                return true;
            }
        }
    }
    // deal with supertypes which were raw
    for (Type superType : ceylonType.getSatisfiedTypes()) {
        if (rawSupertype(superType, flags)) {
            return true;
        }
    }
    return rawSupertype(ceylonType.getExtendedType(), flags);
}
Also used : 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)

Example 13 with Type

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

the class AbstractTransformer method makeTypeParameter.

JCTypeParameter makeTypeParameter(TypeParameter declarationModel, java.util.List<Type> satisfiedTypesForBounds) {
    TypeParameter typeParameterForBounds = declarationModel;
    if (satisfiedTypesForBounds == null) {
        satisfiedTypesForBounds = declarationModel.getSatisfiedTypes();
    }
    // special case for method refinenement where Java doesn't let us refine the parameter bounds
    if (declarationModel.getContainer() instanceof Function) {
        Function method = (Function) declarationModel.getContainer();
        Function refinedMethod = (Function) method.getRefinedDeclaration();
        if (!Decl.equal(method, refinedMethod)) {
            // find the param index
            int index = method.getTypeParameters().indexOf(declarationModel);
            if (index == -1) {
                log.error("Failed to find type parameter index: " + declarationModel.getName());
            } else if (refinedMethod.getTypeParameters().size() > index) {
                // ignore smaller index than size since the typechecker would have found the error
                TypeParameter refinedTP = refinedMethod.getTypeParameters().get(index);
                if (!haveSameBounds(declarationModel, refinedTP)) {
                    // find the right instantiation of that type parameter
                    TypeDeclaration methodContainer = (TypeDeclaration) method.getContainer();
                    TypeDeclaration refinedMethodContainer = (TypeDeclaration) refinedMethod.getContainer();
                    // find the supertype that gave us that method and its type arguments
                    Type supertype = methodContainer.getType().getSupertype(refinedMethodContainer);
                    satisfiedTypesForBounds = new ArrayList<Type>(refinedTP.getSatisfiedTypes().size());
                    for (Type satisfiedType : refinedTP.getSatisfiedTypes()) {
                        // substitute the refined type parameter bounds with the right type arguments
                        satisfiedTypesForBounds.add(satisfiedType.substitute(supertype));
                    }
                    typeParameterForBounds = refinedTP;
                }
            }
        }
    }
    return makeTypeParameter(declarationModel.getName(), satisfiedTypesForBounds, typeParameterForBounds.isCovariant(), typeParameterForBounds.isContravariant());
}
Also used : Function(com.redhat.ceylon.model.typechecker.model.Function) 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) ArrayList(java.util.ArrayList) TypeDeclaration(com.redhat.ceylon.model.typechecker.model.TypeDeclaration)

Example 14 with Type

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

the class CallableBuilder method makeCallableVaryParam.

private ParameterDefinitionBuilder makeCallableVaryParam(long flags, int ii) {
    Type iteratedType = gen.typeFact().getIteratedType(parameterTypes.get(parameterTypes.size() - 1));
    // $call$var()'s variadic parameter is *always* erasred to Sequential
    // even if it's a Variadic+ parameter
    JCExpression type = gen.makeJavaType(gen.typeFact().getSequentialType(iteratedType), AbstractTransformer.JT_RAW);
    ParameterDefinitionBuilder pdb = ParameterDefinitionBuilder.systemParameter(gen, getParamName(ii));
    pdb.modifiers(Flags.FINAL | flags);
    pdb.type(type, null);
    return pdb;
}
Also used : Type(com.redhat.ceylon.model.typechecker.model.Type) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression)

Example 15 with Type

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

the class CallableBuilder method unboundValueMemberReference.

/**
     * Used for "static" value references. For example:
     * <pre>
     *     value x = Integer.plus;
     *     value y = Foo.method;
     *     value z = Outer.Inner;
     * </pre>
     */
public static CallableBuilder unboundValueMemberReference(CeylonTransformer gen, Tree.QualifiedMemberOrTypeExpression qmte, Type typeModel, final TypedDeclaration value) {
    CallBuilder callBuilder = CallBuilder.instance(gen);
    Type qualifyingType = qmte.getTarget().getQualifyingType();
    JCExpression target = gen.naming.makeUnquotedIdent(Unfix.$instance$);
    target = gen.expressionGen().applyErasureAndBoxing(target, qmte.getPrimary().getTypeModel(), true, BoxingStrategy.BOXED, qualifyingType);
    if (gen.expressionGen().isThrowableMessage(qmte)) {
        callBuilder.invoke(gen.utilInvocation().throwableMessage());
        callBuilder.argument(target);
    } else if (gen.expressionGen().isThrowableSuppressed(qmte)) {
        callBuilder.invoke(gen.utilInvocation().suppressedExceptions());
        callBuilder.argument(target);
    } else {
        JCExpression memberName = gen.naming.makeQualifiedName(target, value, Naming.NA_GETTER | Naming.NA_MEMBER);
        if (value instanceof FieldValue) {
            callBuilder.fieldRead(memberName);
        } else {
            callBuilder.invoke(memberName);
        }
    }
    JCExpression innerInvocation = callBuilder.build();
    // use the return type since the value is actually applied
    Type returnType = gen.getReturnTypeOfCallable(typeModel);
    innerInvocation = gen.expressionGen().applyErasureAndBoxing(innerInvocation, returnType, // expression is a Callable
    qmte.getTypeErased(), !CodegenUtil.isUnBoxed(value), BoxingStrategy.BOXED, returnType, 0);
    ParameterList outerPl = new ParameterList();
    Parameter instanceParameter = new Parameter();
    instanceParameter.setName(Naming.name(Unfix.$instance$));
    Value valueModel = new Value();
    instanceParameter.setModel(valueModel);
    Type accessType = gen.getParameterTypeOfCallable(typeModel, 0);
    ;
    if (!value.isShared()) {
        accessType = Decl.getPrivateAccessType(qmte);
    }
    valueModel.setName(instanceParameter.getName());
    valueModel.setInitializerParameter(instanceParameter);
    valueModel.setType(accessType);
    valueModel.setUnboxed(false);
    outerPl.getParameters().add(instanceParameter);
    CallableBuilder outer = new CallableBuilder(gen, null, typeModel, outerPl);
    outer.parameterTypes = outer.getParameterTypesFromParameterModels();
    List<JCStatement> innerBody = List.<JCStatement>of(gen.make().Return(innerInvocation));
    outer.useDefaultTransformation(innerBody);
    outer.companionAccess = Decl.isPrivateAccessRequiringCompanion(qmte);
    return outer;
}
Also used : Type(com.redhat.ceylon.model.typechecker.model.Type) 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) ParameterList(com.redhat.ceylon.model.typechecker.model.ParameterList) TypeParameter(com.redhat.ceylon.model.typechecker.model.TypeParameter) Parameter(com.redhat.ceylon.model.typechecker.model.Parameter) JCTypeParameter(com.sun.tools.javac.tree.JCTree.JCTypeParameter) FieldValue(com.redhat.ceylon.model.loader.model.FieldValue) JCStatement(com.sun.tools.javac.tree.JCTree.JCStatement)

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