Search in sources :

Example 16 with TypeParameter

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

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 getPinnedType(declaration, pr.getType());
}
Also used : Functional(org.eclipse.ceylon.model.typechecker.model.Functional) Function(org.eclipse.ceylon.model.typechecker.model.Function) Type(org.eclipse.ceylon.model.typechecker.model.Type) ModelUtil.appliedType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.appliedType) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) JCTypeParameter(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCTypeParameter) TypedReference(org.eclipse.ceylon.model.typechecker.model.TypedReference) Reference(org.eclipse.ceylon.model.typechecker.model.Reference)

Example 17 with TypeParameter

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

the class BoxingDeclarationVisitor method setBoxingState.

private void setBoxingState(TypedDeclaration declaration, TypedDeclaration refinedDeclaration, Node that) {
    Type type = declaration.getType();
    if (type == null) {
        // an error must have already been reported
        return;
    }
    // fetch the real refined declaration if required
    if (Decl.equal(declaration, refinedDeclaration) && declaration instanceof FunctionOrValue && ((FunctionOrValue) declaration).isParameter() && declaration.getContainer() instanceof Class) {
        // maybe it is really inherited from a field?
        FunctionOrValue methodOrValueForParam = (FunctionOrValue) declaration;
        if (methodOrValueForParam != null) {
            // make sure we get the refined version of that member
            refinedDeclaration = (TypedDeclaration) methodOrValueForParam.getRefinedDeclaration();
        }
    }
    // inherit underlying type constraints
    if (!Decl.equal(refinedDeclaration, declaration)) {
        // simple case
        if (type.getUnderlyingType() == null && refinedDeclaration.getType() != null) {
            if (type.isCached()) {
                type = type.clone();
            }
            type.setUnderlyingType(refinedDeclaration.getType().getUnderlyingType());
            declaration.setType(type);
        }
        // special case for variadics
        if (Decl.isValueParameter(refinedDeclaration)) {
            Parameter parameter = ((FunctionOrValue) refinedDeclaration).getInitializerParameter();
            if (parameter.isSequenced()) {
                // inherit the underlying type of the iterated type
                Type refinedIteratedType = refinedDeclaration.getType().getTypeArgumentList().get(0);
                if (refinedIteratedType.getUnderlyingType() != null) {
                    Type ourIteratedType = type.getTypeArgumentList().get(0);
                    if (ourIteratedType.getUnderlyingType() == null) {
                        if (ourIteratedType.isCached()) {
                            ourIteratedType = ourIteratedType.clone();
                        }
                        ourIteratedType.setUnderlyingType(refinedIteratedType.getUnderlyingType());
                        type.getTypeArgumentList().set(0, ourIteratedType);
                        // make sure we remove those types from the cache otherwise UGLY things happen
                        TypeCache cache = type.getDeclaration().getUnit().getCache();
                        if (cache != null) {
                            cache.remove(ourIteratedType);
                            cache.remove(type);
                        }
                    }
                }
            }
        }
    }
    // abort if our boxing state has already been set
    if (declaration.getUnboxed() != null)
        return;
    // functional parameter return values are always boxed if we're not creating a method for them
    if (declaration instanceof Function && ((Function) declaration).isParameter() && !JvmBackendUtil.createMethod((Function) declaration)) {
        declaration.setUnboxed(false);
        return;
    }
    if (!Decl.equal(refinedDeclaration, declaration)) {
        // make sure refined declarations have already been set
        if (refinedDeclaration.getUnboxed() == null)
            setBoxingState(refinedDeclaration, refinedDeclaration, that);
        // inherit
        declaration.setUnboxed(refinedDeclaration.getUnboxed());
    } else if (declaration instanceof Function && Strategy.useBoxedVoid((Function) declaration) && !(refinedDeclaration.getTypeDeclaration() instanceof TypeParameter) && !CodegenUtil.isContainerFunctionalParameter(refinedDeclaration) && !(refinedDeclaration instanceof Functional && Decl.isMpl((Functional) refinedDeclaration))) {
        declaration.setUnboxed(false);
    } else if ((isCeylonBasicType(type) || Decl.isUnboxedVoid(declaration)) && !(refinedDeclaration.getTypeDeclaration() instanceof TypeParameter) && (refinedDeclaration.getContainer() instanceof Declaration == false || !CodegenUtil.isContainerFunctionalParameter(refinedDeclaration)) && !(refinedDeclaration instanceof Functional && Decl.isMpl((Functional) refinedDeclaration))) {
        boolean unbox = !forceBoxedLocals || !(declaration instanceof Value) || !Decl.isLocal(declaration) || Decl.isParameter(declaration) || Decl.isTransient(declaration);
        // until it's used later by user code
        if (declaration.getOriginalDeclaration() != null && declaration.hasUncheckedNullType())
            unbox = false;
        declaration.setUnboxed(unbox);
    } else if (Decl.isValueParameter(declaration) && CodegenUtil.isContainerFunctionalParameter(declaration) && JvmBackendUtil.createMethod((FunctionOrValue) declaration.getContainer())) {
        Function functionalParameter = (Function) declaration.getContainer();
        TypedDeclaration refinedFrom = (TypedDeclaration) CodegenUtil.getTopmostRefinedDeclaration(functionalParameter, optimisedMethodSpecifiersToMethods);
        if (Decl.equal(refinedFrom, functionalParameter)) {
            // not a method return type (where void would be considered unboxed).
            if (declaration.getUnit().getAnythingType().isExactly(declaration.getType()) || declaration.getUnit().isOptionalType(declaration.getType())) {
                declaration.setUnboxed(false);
            } else {
                declaration.setUnboxed(true);
            }
        } else {
            // make sure refined declarations have already been set
            if (refinedFrom.getUnboxed() == null)
                setBoxingState(refinedFrom, refinedFrom, that);
            // inherit
            declaration.setUnboxed(refinedFrom.getUnboxed());
        }
    } else {
        declaration.setUnboxed(false);
    }
    // Any "@boxed" or "@unboxed" compiler annotation overrides
    boxFromAnnotation(declaration, that);
}
Also used : Functional(org.eclipse.ceylon.model.typechecker.model.Functional) Function(org.eclipse.ceylon.model.typechecker.model.Function) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) AbstractTransformer.isPinnedType(org.eclipse.ceylon.compiler.java.codegen.AbstractTransformer.isPinnedType) Type(org.eclipse.ceylon.model.typechecker.model.Type) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue) Value(org.eclipse.ceylon.model.typechecker.model.Value) Parameter(org.eclipse.ceylon.model.typechecker.model.Parameter) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) Class(org.eclipse.ceylon.model.typechecker.model.Class) TypeCache(org.eclipse.ceylon.model.typechecker.context.TypeCache) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) FunctionalParameterDeclaration(org.eclipse.ceylon.compiler.typechecker.tree.Tree.FunctionalParameterDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) AttributeDeclaration(org.eclipse.ceylon.compiler.typechecker.tree.Tree.AttributeDeclaration) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)

Example 18 with TypeParameter

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

the class BoxingVisitor method hasTypeParameterWithConstraintsOutsideScopeResolved.

private boolean hasTypeParameterWithConstraintsOutsideScopeResolved(Type type, Scope scope) {
    if (type == null)
        return false;
    if (type.isUnion()) {
        java.util.List<Type> caseTypes = type.getCaseTypes();
        for (Type pt : caseTypes) {
            if (hasTypeParameterWithConstraintsOutsideScopeResolved(pt, scope))
                return true;
        }
        return false;
    }
    if (type.isIntersection()) {
        java.util.List<Type> satisfiedTypes = type.getSatisfiedTypes();
        for (Type pt : satisfiedTypes) {
            if (hasTypeParameterWithConstraintsOutsideScopeResolved(pt, scope))
                return true;
        }
        return false;
    }
    TypeDeclaration declaration = type.getDeclaration();
    if (declaration == null)
        return false;
    if (type.isTypeParameter()) {
        // only look at it if it is defined outside our scope
        Scope typeParameterScope = declaration.getContainer();
        while (scope != null) {
            if (Decl.equalScopes(scope, typeParameterScope))
                return false;
            scope = scope.getContainer();
        }
        TypeParameter tp = (TypeParameter) declaration;
        Boolean nonErasedBounds = tp.hasNonErasedBounds();
        if (nonErasedBounds == null)
            visitTypeParameter(tp);
        return nonErasedBounds != null ? nonErasedBounds.booleanValue() : false;
    }
    // now check its type parameters
    for (Type pt : type.getTypeArgumentList()) {
        if (hasTypeParameterWithConstraintsOutsideScopeResolved(pt, scope))
            return true;
    }
    // no problem here
    return false;
}
Also used : Type(org.eclipse.ceylon.model.typechecker.model.Type) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) Scope(org.eclipse.ceylon.model.typechecker.model.Scope) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)

Example 19 with TypeParameter

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

the class CallableBuilder method buildTypeConstructor.

protected JCExpression buildTypeConstructor(Type callableType, JCNewClass callableInstance) {
    JCExpression result;
    // Wrap in an anonymous TypeConstructor subcla
    MethodDefinitionBuilder rawApply = MethodDefinitionBuilder.systemMethod(gen, Naming.Unfix.apply.toString());
    rawApply.modifiers(Flags.PUBLIC);
    rawApply.isOverride(true);
    // for (TypeParameter tp : typeModel.getDeclaration().getTypeParameters()) {
    // apply.typeParameter(tp);
    // }
    rawApply.resultType(new TransformedType(gen.makeJavaType(callableType, AbstractTransformer.JT_RAW)));
    {
        ParameterDefinitionBuilder pdb = ParameterDefinitionBuilder.systemParameter(gen, "applied");
        pdb.modifiers(Flags.FINAL);
        pdb.type(new TransformedType(gen.make().TypeArray(gen.make().Type(gen.syms().ceylonTypeDescriptorType))));
        rawApply.parameter(pdb);
    }
    rawApply.body(List.<JCStatement>of(gen.make().Return(gen.make().Apply(null, gen.naming.makeUnquotedIdent(Naming.Unfix.$apply$.toString()), List.<JCExpression>of(gen.naming.makeUnquotedIdent("applied"))))));
    MethodDefinitionBuilder typedApply = MethodDefinitionBuilder.systemMethod(gen, Naming.Unfix.$apply$.toString());
    typedApply.modifiers(Flags.PRIVATE);
    // for (TypeParameter tp : typeModel.getDeclaration().getTypeParameters()) {
    // apply.typeParameter(tp);
    // }
    typedApply.resultType(new TransformedType(gen.makeJavaType(callableType)));
    {
        ParameterDefinitionBuilder pdb = ParameterDefinitionBuilder.systemParameter(gen, "applied");
        pdb.modifiers(Flags.FINAL);
        pdb.type(new TransformedType(gen.make().TypeArray(gen.make().Type(gen.syms().ceylonTypeDescriptorType))));
        typedApply.parameter(pdb);
    }
    ListBuffer<JCTypeParameter> typeParameters = new ListBuffer<JCTypeParameter>();
    for (TypeParameter typeParameter : Strategy.getEffectiveTypeParameters(typeModel.getDeclaration())) {
        Type typeArgument = typeModel.getTypeArguments().get(typeParameter);
        typeParameters.add(gen.makeTypeParameter(typeParameter, null));
        typedApply.body(gen.makeVar(Flags.FINAL, gen.naming.getTypeArgumentDescriptorName(typeParameter), gen.make().Type(gen.syms().ceylonTypeDescriptorType), gen.make().Indexed(gen.makeUnquotedIdent("applied"), gen.make().Literal(typeModel.getTypeArgumentList().indexOf(typeArgument)))));
    }
    typedApply.body(gen.make().Return(callableInstance));
    // typedApply.body(body.toList());
    MethodDefinitionBuilder ctor = MethodDefinitionBuilder.constructor(gen, false);
    ctor.body(gen.make().Exec(gen.make().Apply(null, gen.naming.makeSuper(), List.<JCExpression>of(gen.make().Literal(typeModel.asString(true))))));
    SyntheticName n = gen.naming.synthetic(typeModel.getDeclaration().getName());
    JCClassDecl classDef = gen.make().ClassDef(gen.make().Modifiers(0, List.<JCAnnotation>nil()), // name,
    n.asName(), typeParameters.toList(), // extending
    gen.make().QualIdent(gen.syms().ceylonAbstractTypeConstructorType.tsym), // implementing,
    List.<JCExpression>nil(), List.<JCTree>of(ctor.build(), rawApply.build(), typedApply.build()));
    result = gen.make().LetExpr(List.<JCStatement>of(classDef), gen.make().NewClass(null, null, n.makeIdent(), List.<JCExpression>nil(), // List.<JCExpression>of(gen.make().Literal(typeModel.asString(true))),
    null));
    return result;
}
Also used : TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) JCTypeParameter(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCTypeParameter) JCClassDecl(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCClassDecl) ListBuffer(org.eclipse.ceylon.langtools.tools.javac.util.ListBuffer) SyntheticName(org.eclipse.ceylon.compiler.java.codegen.Naming.SyntheticName) JCStatement(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCStatement) JCTypeParameter(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCTypeParameter) Type(org.eclipse.ceylon.model.typechecker.model.Type) JCExpression(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression) JCAnnotation(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCAnnotation)

Example 20 with TypeParameter

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

the class ClassOrPackageDoc method writeTypeParameters.

protected final void writeTypeParameters(List<TypeParameter> typeParameters, Referenceable scope) throws IOException {
    if (typeParameters != null && !typeParameters.isEmpty()) {
        write("&lt;");
        write("<span class='type-parameter'>");
        boolean first = true;
        for (TypeParameter typeParam : typeParameters) {
            if (first) {
                first = false;
            } else {
                write(", ");
            }
            if (typeParam.isContravariant()) {
                write("<span class='type-parameter-keyword'>in </span>");
            }
            if (typeParam.isCovariant()) {
                write("<span class='type-parameter-keyword'>out </span>");
            }
            write(typeParam.getName());
            if (typeParam.isDefaulted() && typeParam.getDefaultTypeArgument() != null) {
                write("<span class='type-parameter'> = </span>");
                write("<span class='type-parameter-value'>");
                write(linkRenderer().to(typeParam.getDefaultTypeArgument()).useScope(scope).getLink());
                write("</span>");
            }
        }
        write("</span>");
        write("&gt;");
    }
}
Also used : TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter)

Aggregations

TypeParameter (org.eclipse.ceylon.model.typechecker.model.TypeParameter)181 Type (org.eclipse.ceylon.model.typechecker.model.Type)138 TypeDeclaration (org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)82 ArrayList (java.util.ArrayList)57 ModelUtil.appliedType (org.eclipse.ceylon.model.typechecker.model.ModelUtil.appliedType)57 Tree (org.eclipse.ceylon.compiler.typechecker.tree.Tree)54 UnknownType (org.eclipse.ceylon.model.typechecker.model.UnknownType)46 Declaration (org.eclipse.ceylon.model.typechecker.model.Declaration)45 ModelUtil.intersectionType (org.eclipse.ceylon.model.typechecker.model.ModelUtil.intersectionType)35 TypedDeclaration (org.eclipse.ceylon.model.typechecker.model.TypedDeclaration)32 ClassOrInterface (org.eclipse.ceylon.model.typechecker.model.ClassOrInterface)30 Function (org.eclipse.ceylon.model.typechecker.model.Function)29 AnalyzerUtil.getTupleType (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTupleType)28 AnalyzerUtil.spreadType (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.spreadType)28 Parameter (org.eclipse.ceylon.model.typechecker.model.Parameter)28 IntersectionType (org.eclipse.ceylon.model.typechecker.model.IntersectionType)27 JCTypeParameter (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCTypeParameter)26 Class (org.eclipse.ceylon.model.typechecker.model.Class)26 UnionType (org.eclipse.ceylon.model.typechecker.model.UnionType)25 HashMap (java.util.HashMap)24