Search in sources :

Example 46 with Function

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

the class BoxingVisitor method visit.

@Override
public void visit(QualifiedMemberExpression that) {
    super.visit(that);
    // handle errors gracefully
    if (that.getDeclaration() == null)
        return;
    if (that.getMemberOperator() instanceof Tree.SafeMemberOp) {
        TypedDeclaration decl = (TypedDeclaration) that.getDeclaration();
        if (CodegenUtil.isRaw(decl))
            CodegenUtil.markRaw(that);
        if (CodegenUtil.hasTypeErased(decl))
            CodegenUtil.markTypeErased(that);
        if (CodegenUtil.hasUntrustedType(decl) || hasTypeParameterWithConstraintsOutsideScope(decl.getType(), that.getScope()))
            CodegenUtil.markUntrustedType(that);
    // we must be boxed, since safe member op "?." returns an optional type
    //return;
    } else if (that.getMemberOperator() instanceof Tree.MemberOp && Decl.isValueTypeDecl(that.getPrimary()) && CodegenUtil.isUnBoxed(that.getPrimary())) {
        // it's unboxed if it's an unboxable type or it's declared void
        if (Decl.isValueTypeDecl((TypedDeclaration) that.getDeclaration()) || (that.getDeclaration() instanceof Function && ((Function) that.getDeclaration()).isDeclaredVoid()))
            CodegenUtil.markUnBoxed(that);
        if (CodegenUtil.isRaw((TypedDeclaration) that.getDeclaration()))
            CodegenUtil.markRaw(that);
        if (CodegenUtil.hasTypeErased((TypedDeclaration) that.getDeclaration()))
            CodegenUtil.markTypeErased(that);
    } else {
        propagateFromDeclaration(that, (TypedDeclaration) that.getDeclaration());
    }
    // be (ex: <String>), and in that case we will generate a proper Sequential<String> which is not raw at all
    if (that.getMemberOperator() instanceof Tree.SpreadOp) {
        // find the return element type
        Type elementType = that.getTarget().getType();
        CodegenUtil.markTypeErased(that, hasErasure(elementType));
    }
    if (ExpressionTransformer.isSuperOrSuperOf(that.getPrimary())) {
        // if the target is an interface whose type arguments have been turned to raw, make this expression
        // as erased
        Reference target = that.getTarget();
        if (target != null && target.getQualifyingType() != null && target.getQualifyingType().getDeclaration() instanceof Interface) {
            if (isRaw(target.getQualifyingType())) {
                CodegenUtil.markTypeErased(that);
            } else // See note in ClassTransformer.makeDelegateToCompanion for a similar test
            {
                TypeDeclaration declaration = target.getQualifyingType().getDeclaration();
                if (needsRawCastForMixinSuperCall(declaration, target.getType()))
                    CodegenUtil.markTypeErased(that);
            }
        }
    }
    Type primaryType;
    if (that.getPrimary() instanceof Tree.Package || that.getTarget() == null) {
        primaryType = that.getPrimary().getTypeModel();
    } else {
        primaryType = that.getTarget().getQualifyingType();
    }
    if (primaryType != null && (isRaw(primaryType) || willEraseToSequence(primaryType)) && that.getTarget() != null && that.getTarget().getDeclaration() instanceof TypedDeclaration && CodegenUtil.containsTypeParameter(((TypedDeclaration) that.getTarget().getDeclaration()).getType())) {
        CodegenUtil.markTypeErased(that);
    }
    if (isRaw(primaryType) && !that.getTypeModel().getDeclaration().getTypeParameters().isEmpty()) {
        CodegenUtil.markRaw(that);
    }
}
Also used : TypedDeclaration(com.redhat.ceylon.model.typechecker.model.TypedDeclaration) Function(com.redhat.ceylon.model.typechecker.model.Function) Type(com.redhat.ceylon.model.typechecker.model.Type) Reference(com.redhat.ceylon.model.typechecker.model.Reference) Tree(com.redhat.ceylon.compiler.typechecker.tree.Tree) TypeDeclaration(com.redhat.ceylon.model.typechecker.model.TypeDeclaration) Interface(com.redhat.ceylon.model.typechecker.model.Interface)

Example 47 with Function

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

the class AbstractTransformer method makeTypedDeclarationTypeDescriptorResolved.

private JCExpression makeTypedDeclarationTypeDescriptorResolved(TypedDeclaration declaration) {
    // figure out the method name
    String methodName = declaration.getPrefixedName();
    List<JCExpression> arguments;
    if (declaration instanceof Function)
        arguments = makeReifiedTypeArgumentsResolved(getTypeArguments((Function) declaration), true);
    else
        arguments = List.nil();
    if (declaration.isToplevel()) {
        JCExpression getterClassNameExpr;
        if (declaration instanceof Function) {
            getterClassNameExpr = naming.makeName(declaration, Naming.NA_FQ | Naming.NA_WRAPPER);
        } else {
            String getterClassName = Naming.getAttrClassName(declaration, 0);
            getterClassNameExpr = naming.makeUnquotedIdent(getterClassName);
        }
        arguments = arguments.prepend(makeSelect(getterClassNameExpr, "class"));
    } else
        arguments = arguments.prepend(make().Literal(methodName));
    JCMethodInvocation typedDeclarationDescriptor = make().Apply(null, makeSelect(makeTypeDescriptorType(), "functionOrValue"), arguments);
    // see if the declaration has a container too
    Declaration enclosingDeclaration = getDeclarationContainer(declaration);
    JCExpression containerType = null;
    if (enclosingDeclaration instanceof TypedDeclaration)
        containerType = makeTypedDeclarationTypeDescriptorResolved((TypedDeclaration) enclosingDeclaration);
    else if (enclosingDeclaration instanceof TypeDeclaration) {
        Type qualifyingType = ((TypeDeclaration) enclosingDeclaration).getType();
        containerType = makeReifiedTypeArgumentResolved(qualifyingType, true);
    }
    if (containerType == null) {
        return typedDeclarationDescriptor;
    } else {
        return make().Apply(null, makeSelect(makeTypeDescriptorType(), "member"), List.of(containerType, typedDeclarationDescriptor));
    }
}
Also used : Function(com.redhat.ceylon.model.typechecker.model.Function) JCMethodInvocation(com.sun.tools.javac.tree.JCTree.JCMethodInvocation) TypedDeclaration(com.redhat.ceylon.model.typechecker.model.TypedDeclaration) Type(com.redhat.ceylon.model.typechecker.model.Type) ModelUtil.appliedType(com.redhat.ceylon.model.typechecker.model.ModelUtil.appliedType) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) TypedDeclaration(com.redhat.ceylon.model.typechecker.model.TypedDeclaration) Declaration(com.redhat.ceylon.model.typechecker.model.Declaration) TypeDeclaration(com.redhat.ceylon.model.typechecker.model.TypeDeclaration) TypeDeclaration(com.redhat.ceylon.model.typechecker.model.TypeDeclaration)

Example 48 with Function

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

the class AbstractTransformer method collectQualifyingTypeArguments.

/**
     * Collects all the type parameters and arguments required for an interface that's been pulled up to the
     * toplevel, including its containing type and method type parameters.
     */
private void collectQualifyingTypeArguments(java.util.List<TypeParameter> qualifyingTypeParameters, Map<TypeParameter, Type> qualifyingTypeArguments, java.util.List<Reference> qualifyingTypes) {
    // make sure we only add type parameters with the same name once, as duplicates are erased from the target interface
    // since they cannot be accessed
    Set<String> names = new HashSet<String>();
    // walk the qualifying types backwards to make sure we only add a TP with the same name once and the outer one wins
    for (int i = qualifyingTypes.size() - 1; i >= 0; i--) {
        Reference qualifiedType = qualifyingTypes.get(i);
        Map<TypeParameter, Type> tas = qualifiedType.getTypeArguments();
        java.util.List<TypeParameter> tps = ((Generic) qualifiedType.getDeclaration()).getTypeParameters();
        // add any type params for this type
        if (tps != null) {
            int index = 0;
            for (TypeParameter tp : tps) {
                // add it only once
                if (names.add(tp.getName())) {
                    // start putting all these type parameters at 0 and then in order
                    // so that outer type params end up before inner type params but
                    // order is preserved within each type
                    qualifyingTypeParameters.add(index++, tp);
                    qualifyingTypeArguments.put(tp, tas.get(tp));
                }
            }
        }
        // add any container method TP
        Declaration declaration = qualifiedType.getDeclaration();
        if (Decl.isLocal(declaration)) {
            Scope scope = declaration.getContainer();
            // collect every container method until the next type or package
            java.util.List<Function> methods = new LinkedList<Function>();
            while (scope != null && scope instanceof ClassOrInterface == false && scope instanceof Package == false) {
                if (scope instanceof Function) {
                    methods.add((Function) scope);
                }
                scope = scope.getContainer();
            }
            // methods are sorted inner to outer, which is the order we're following here for types
            for (Function method : methods) {
                java.util.List<TypeParameter> methodTypeParameters = method.getTypeParameters();
                if (methodTypeParameters != null) {
                    int index = 0;
                    for (TypeParameter tp : methodTypeParameters) {
                        // add it only once
                        if (names.add(tp.getName())) {
                            // start putting all these type parameters at 0 and then in order
                            // so that outer type params end up before inner type params but
                            // order is preserved within each type
                            qualifyingTypeParameters.add(index++, tp);
                            qualifyingTypeArguments.put(tp, tp.getType());
                        }
                    }
                }
            }
        }
    }
}
Also used : ClassOrInterface(com.redhat.ceylon.model.typechecker.model.ClassOrInterface) 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) Generic(com.redhat.ceylon.model.typechecker.model.Generic) LinkedList(java.util.LinkedList) 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) Scope(com.redhat.ceylon.model.typechecker.model.Scope) TypedDeclaration(com.redhat.ceylon.model.typechecker.model.TypedDeclaration) Declaration(com.redhat.ceylon.model.typechecker.model.Declaration) TypeDeclaration(com.redhat.ceylon.model.typechecker.model.TypeDeclaration) Package(com.redhat.ceylon.model.typechecker.model.Package) HashSet(java.util.HashSet)

Example 49 with Function

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

the class AnnotationInvocation method encode.

/**
     * Encode this invocation into a {@code @AnnotationInstantiation} 
     * (if the annotation constructors just calls the annotation class)
     * or {@code @AnnotationInstantiationTree} 
     * (if the annotation constructor calls another annotation constructor)
     */
public JCAnnotation encode(AbstractTransformer gen, ListBuffer<JCExpression> instantiations) {
    ListBuffer<JCExpression> arguments = ListBuffer.lb();
    for (AnnotationArgument argument : getAnnotationArguments()) {
        arguments.append(gen.make().Literal(argument.getTerm().encode(gen, instantiations)));
    }
    JCExpression primary;
    if (isInstantiation()) {
        primary = gen.makeJavaType(getAnnotationClassType());
    } else {
        primary = gen.naming.makeName((Function) getPrimary(), Naming.NA_FQ | Naming.NA_WRAPPER);
    }
    JCAnnotation atInstantiation = gen.make().Annotation(gen.make().Type(gen.syms().ceylonAtAnnotationInstantiationType), com.sun.tools.javac.util.List.<JCExpression>of(gen.make().Assign(gen.naming.makeUnquotedIdent("arguments"), gen.make().NewArray(null, null, arguments.toList())), gen.make().Assign(gen.naming.makeUnquotedIdent("primary"), gen.naming.makeQualIdent(primary, "class"))));
    if (instantiations.isEmpty()) {
        return atInstantiation;
    } else {
        return gen.make().Annotation(gen.make().Type(gen.syms().ceylonAtAnnotationInstantiationTreeType), com.sun.tools.javac.util.List.<JCExpression>of(gen.make().NewArray(null, null, instantiations.prepend(atInstantiation).toList())));
    }
}
Also used : Function(com.redhat.ceylon.model.typechecker.model.Function) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) JCAnnotation(com.sun.tools.javac.tree.JCTree.JCAnnotation)

Example 50 with Function

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

the class AnnotationInvocationVisitor method annoClass.

public static Class annoClass(Tree.InvocationExpression invocation) {
    Declaration declaration = ((Tree.BaseMemberOrTypeExpression) invocation.getPrimary()).getDeclaration();
    Set<Declaration> ctors = new HashSet<Declaration>();
    while (declaration instanceof Function) {
        if (!ctors.add(declaration)) {
            throw new BugException(invocation, "recursive annotation constructor");
        }
        declaration = ((AnnotationInvocation) ((Function) declaration).getAnnotationConstructor()).getPrimary();
    }
    if (declaration instanceof Class) {
        return (Class) declaration;
    } else {
        throw new BugException(invocation, "invocation primary has unexpected declaration: " + declaration);
    }
}
Also used : Function(com.redhat.ceylon.model.typechecker.model.Function) Class(com.redhat.ceylon.model.typechecker.model.Class) Declaration(com.redhat.ceylon.model.typechecker.model.Declaration) TypeDeclaration(com.redhat.ceylon.model.typechecker.model.TypeDeclaration) HashSet(java.util.HashSet)

Aggregations

Function (com.redhat.ceylon.model.typechecker.model.Function)74 TypeDeclaration (com.redhat.ceylon.model.typechecker.model.TypeDeclaration)35 TypedDeclaration (com.redhat.ceylon.model.typechecker.model.TypedDeclaration)35 Declaration (com.redhat.ceylon.model.typechecker.model.Declaration)33 Type (com.redhat.ceylon.model.typechecker.model.Type)33 TypeParameter (com.redhat.ceylon.model.typechecker.model.TypeParameter)26 JCExpression (com.sun.tools.javac.tree.JCTree.JCExpression)26 FunctionOrValue (com.redhat.ceylon.model.typechecker.model.FunctionOrValue)25 Value (com.redhat.ceylon.model.typechecker.model.Value)25 Class (com.redhat.ceylon.model.typechecker.model.Class)23 Tree (com.redhat.ceylon.compiler.typechecker.tree.Tree)22 Parameter (com.redhat.ceylon.model.typechecker.model.Parameter)20 JCTree (com.sun.tools.javac.tree.JCTree)18 TypedReference (com.redhat.ceylon.model.typechecker.model.TypedReference)17 JCNewClass (com.sun.tools.javac.tree.JCTree.JCNewClass)17 ArrayList (java.util.ArrayList)14 ParameterList (com.redhat.ceylon.model.typechecker.model.ParameterList)13 ModelUtil.appliedType (com.redhat.ceylon.model.typechecker.model.ModelUtil.appliedType)12 MethodDeclaration (com.redhat.ceylon.compiler.typechecker.tree.Tree.MethodDeclaration)11 ClassOrInterface (com.redhat.ceylon.model.typechecker.model.ClassOrInterface)11