Search in sources :

Example 6 with TypedReference

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

the class ClassTransformer method addAmbiguousMember.

private void addAmbiguousMember(ClassDefinitionBuilder classBuilder, Interface model, String name) {
    Declaration member = model.getMember(name, null, false);
    Type satisfiedType = model.getType().getSupertype(model);
    if (member instanceof Class) {
        Class klass = (Class) member;
        if (Strategy.generateInstantiator(member) && !klass.hasConstructors()) {
            // instantiator method implementation
            generateInstantiatorDelegate(classBuilder, satisfiedType, model, klass, null, model.getType(), false);
        }
        if (klass.hasConstructors()) {
            for (Declaration m : klass.getMembers()) {
                if (m instanceof Constructor && Strategy.generateInstantiator(m)) {
                    Constructor ctor = (Constructor) m;
                    generateInstantiatorDelegate(classBuilder, satisfiedType, model, klass, ctor, model.getType(), false);
                }
            }
        }
    } else if (member instanceof Function) {
        Function method = (Function) member;
        final TypedReference typedMember = satisfiedType.getTypedMember(method, Collections.<Type>emptyList());
        java.util.List<java.util.List<Type>> producedTypeParameterBounds = producedTypeParameterBounds(typedMember, method);
        final java.util.List<TypeParameter> typeParameters = method.getTypeParameters();
        final java.util.List<Parameter> parameters = method.getFirstParameterList().getParameters();
        for (Parameter param : parameters) {
            if (Strategy.hasDefaultParameterOverload(param)) {
                MethodDefinitionBuilder overload = new DefaultedArgumentMethodTyped(null, MethodDefinitionBuilder.method(this, method), typedMember, true).makeOverload(method.getFirstParameterList(), param, typeParameters);
                overload.modifiers(PUBLIC | ABSTRACT);
                classBuilder.method(overload);
            }
        }
        final MethodDefinitionBuilder concreteMemberDelegate = makeDelegateToCompanion(null, typedMember, model.getType(), PUBLIC | ABSTRACT, method.getTypeParameters(), producedTypeParameterBounds, typedMember.getType(), naming.selector(method), method.getFirstParameterList().getParameters(), ((Function) member).getTypeErased(), null, DelegateType.OTHER, false);
        classBuilder.method(concreteMemberDelegate);
    } else if (member instanceof Value || member instanceof Setter) {
        TypedDeclaration attr = (TypedDeclaration) member;
        final TypedReference typedMember = satisfiedType.getTypedMember(attr, Collections.<Type>emptyList());
        if (member instanceof Value) {
            final MethodDefinitionBuilder getterDelegate = makeDelegateToCompanion(null, typedMember, model.getType(), PUBLIC | ABSTRACT, Collections.<TypeParameter>emptyList(), Collections.<java.util.List<Type>>emptyList(), typedMember.getType(), Naming.getGetterName(attr), Collections.<Parameter>emptyList(), attr.getTypeErased(), null, DelegateType.OTHER, false);
            classBuilder.method(getterDelegate);
        }
        if (member instanceof Setter) {
            final MethodDefinitionBuilder setterDelegate = makeDelegateToCompanion(null, typedMember, model.getType(), PUBLIC | ABSTRACT, Collections.<TypeParameter>emptyList(), Collections.<java.util.List<Type>>emptyList(), typeFact().getAnythingType(), Naming.getSetterName(attr), Collections.<Parameter>singletonList(((Setter) member).getParameter()), ((Setter) member).getTypeErased(), null, DelegateType.OTHER, false);
            classBuilder.method(setterDelegate);
        }
    }
}
Also used : TypedDeclaration(com.redhat.ceylon.model.typechecker.model.TypedDeclaration) TypedReference(com.redhat.ceylon.model.typechecker.model.TypedReference) ThrowerCatchallConstructor(com.redhat.ceylon.compiler.java.codegen.recovery.ThrowerCatchallConstructor) Constructor(com.redhat.ceylon.model.typechecker.model.Constructor) Function(com.redhat.ceylon.model.typechecker.model.Function) Type(com.redhat.ceylon.model.typechecker.model.Type) FunctionOrValue(com.redhat.ceylon.model.typechecker.model.FunctionOrValue) JavaBeanValue(com.redhat.ceylon.model.loader.model.JavaBeanValue) Value(com.redhat.ceylon.model.typechecker.model.Value) Setter(com.redhat.ceylon.model.typechecker.model.Setter) TypeParameter(com.redhat.ceylon.model.typechecker.model.TypeParameter) Parameter(com.redhat.ceylon.model.typechecker.model.Parameter) Class(com.redhat.ceylon.model.typechecker.model.Class) JCNewClass(com.sun.tools.javac.tree.JCTree.JCNewClass) ArrayList(java.util.ArrayList) AnnotationList(com.redhat.ceylon.compiler.typechecker.tree.Tree.AnnotationList) List(com.sun.tools.javac.util.List) ParameterList(com.redhat.ceylon.model.typechecker.model.ParameterList) TypedDeclaration(com.redhat.ceylon.model.typechecker.model.TypedDeclaration) Declaration(com.redhat.ceylon.model.typechecker.model.Declaration) TypeDeclaration(com.redhat.ceylon.model.typechecker.model.TypeDeclaration) MethodDeclaration(com.redhat.ceylon.compiler.typechecker.tree.Tree.MethodDeclaration) AttributeDeclaration(com.redhat.ceylon.compiler.typechecker.tree.Tree.AttributeDeclaration)

Example 7 with TypedReference

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

the class ExpressionTransformer method transformExpression.

//
// Any sort of expression
JCExpression transformExpression(final TypedDeclaration declaration, final Tree.Term expr) {
    // make sure we use the best declaration for boxing and type
    TypedReference typedRef = getTypedReference(declaration);
    TypedReference nonWideningTypedRef = nonWideningTypeDecl(typedRef);
    Type nonWideningType = nonWideningType(typedRef, nonWideningTypedRef);
    // the non-widening type of the innermost callable
    if (declaration instanceof Functional && Decl.isMpl((Functional) declaration)) {
        for (int i = ((Functional) declaration).getParameterLists().size(); i > 1; i--) {
            nonWideningType = getReturnTypeOfCallable(nonWideningType);
        }
    }
    // respect the refining definition of optionality
    nonWideningType = propagateOptionality(declaration.getType(), nonWideningType);
    BoxingStrategy boxing = CodegenUtil.getBoxingStrategy(nonWideningTypedRef.getDeclaration());
    return transformExpression(expr, boxing, nonWideningType);
}
Also used : Functional(com.redhat.ceylon.model.typechecker.model.Functional) Type(com.redhat.ceylon.model.typechecker.model.Type) TypedReference(com.redhat.ceylon.model.typechecker.model.TypedReference)

Example 8 with TypedReference

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

the class MethodDefinitionBuilder method resultType.

public MethodDefinitionBuilder resultType(Function method, int flags) {
    if (method.isParameter()) {
        if (Decl.isUnboxedVoid(method) && !Strategy.useBoxedVoid(method)) {
            return resultType(gen.makeJavaTypeAnnotations(method, false), gen.make().Type(gen.syms().voidType));
        } else {
            Parameter parameter = method.getInitializerParameter();
            Type resultType = parameter.getType();
            for (int ii = 1; ii < method.getParameterLists().size(); ii++) {
                resultType = gen.typeFact().getCallableType(resultType);
            }
            return resultType(gen.makeJavaType(resultType, CodegenUtil.isUnBoxed(method) ? 0 : AbstractTransformer.JT_NO_PRIMITIVES), method);
        }
    }
    TypedReference typedRef = gen.getTypedReference(method);
    TypedReference nonWideningTypedRef = gen.nonWideningTypeDecl(typedRef);
    Type nonWideningType = gen.nonWideningType(typedRef, nonWideningTypedRef);
    if (method.isActual() && CodegenUtil.hasTypeErased(method))
        flags |= AbstractTransformer.JT_RAW;
    return resultType(makeResultType(nonWideningTypedRef.getDeclaration(), nonWideningType, flags), method);
}
Also used : Type(com.redhat.ceylon.model.typechecker.model.Type) TypedReference(com.redhat.ceylon.model.typechecker.model.TypedReference) TypeParameter(com.redhat.ceylon.model.typechecker.model.TypeParameter) Parameter(com.redhat.ceylon.model.typechecker.model.Parameter) JCTypeParameter(com.sun.tools.javac.tree.JCTree.JCTypeParameter)

Example 9 with TypedReference

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

the class MethodDefinitionBuilder method getNonWideningParam.

public NonWideningParam getNonWideningParam(TypedReference typedRef, WideningRules wideningRules) {
    TypedDeclaration nonWideningDecl = null;
    int flags = 0;
    Type nonWideningType;
    FunctionOrValue mov = (FunctionOrValue) typedRef.getDeclaration();
    if (Decl.isValue(mov)) {
        TypedReference nonWideningTypedRef = gen.nonWideningTypeDecl(typedRef);
        nonWideningType = gen.nonWideningType(typedRef, nonWideningTypedRef);
        nonWideningDecl = nonWideningTypedRef.getDeclaration();
    } else {
        // Stef: So here's the thing. I know this is wrong for Function where we should do getFullType(), BUT
        // lots of methods call this and then feed the output into AT.makeJavaType(TypedDeclaration typeDecl, Type type, int flags)
        // which adds the Callable type, so if we fix it here we have to remove it from there and there's lots of callers of that
        // function which rely on its behaviour and frankly I've had enough of this refactoring, so a few callers of this function
        // have to add the Callable back. It sucks, yeah, but so far it works, which is amazing enough that I don't want to touch it
        // any more. More ambitious/courageous people are welcome to fix this properly.
        nonWideningType = typedRef.getType();
        nonWideningDecl = mov;
    }
    if (!CodegenUtil.isUnBoxed(nonWideningDecl))
        flags |= AbstractTransformer.JT_NO_PRIMITIVES;
    // make sure we don't accidentally narrow value parameters that would be erased in the topmost declaration
    if (wideningRules != WideningRules.NONE && mov instanceof Value) {
        TypedDeclaration refinedParameter = (TypedDeclaration) CodegenUtil.getTopmostRefinedDeclaration(mov);
        // mixin bridge methods have the same rules as when refining stuff except they are their own refined decl
        if (wideningRules == WideningRules.FOR_MIXIN || !Decl.equal(refinedParameter, mov)) {
            Type refinedParameterType;
            // in the refined parameter type
            if (refinedParameter instanceof Function)
                refinedParameterType = refinedParameter.appliedTypedReference(null, Collections.<Type>emptyList()).getFullType();
            else
                refinedParameterType = refinedParameter.getType();
            // if the supertype method itself got erased to Object, we can't do better than this
            if (gen.willEraseToObject(refinedParameterType) && !gen.willEraseToBestBounds(mov))
                nonWideningType = gen.typeFact().getObjectType();
            else if (CodegenUtil.isRaw(refinedParameter)) {
                flags |= AbstractTransformer.JT_RAW;
            } else {
                flags |= AbstractTransformer.JT_NARROWED;
            }
        }
    }
    // keep in sync with gen.willEraseToBestBounds()
    if (wideningRules != WideningRules.NONE && (gen.typeFact().isUnion(nonWideningType) || gen.typeFact().isIntersection(nonWideningType))) {
        final Type refinedType = ((TypedDeclaration) CodegenUtil.getTopmostRefinedDeclaration(nonWideningDecl)).getType();
        if (refinedType.isTypeParameter() && !refinedType.getSatisfiedTypes().isEmpty()) {
            nonWideningType = refinedType.getSatisfiedTypes().get(0);
            // Could be parameterized, and type param won't be in scope, so have to go raw
            flags |= AbstractTransformer.JT_RAW;
        }
    }
    // this is to be done on the parameter's containing method, to see if that method must have raw parameters
    if (mov.isParameter() && mov.getContainer() instanceof Declaration && gen.rawParameters((Declaration) mov.getContainer())) {
        flags |= AbstractTransformer.JT_RAW;
    }
    return new NonWideningParam(flags, nonWideningType, nonWideningDecl);
}
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) TypedReference(com.redhat.ceylon.model.typechecker.model.TypedReference) FunctionOrValue(com.redhat.ceylon.model.typechecker.model.FunctionOrValue) Value(com.redhat.ceylon.model.typechecker.model.Value) TypedDeclaration(com.redhat.ceylon.model.typechecker.model.TypedDeclaration) Declaration(com.redhat.ceylon.model.typechecker.model.Declaration) TypeDeclaration(com.redhat.ceylon.model.typechecker.model.TypeDeclaration) FunctionOrValue(com.redhat.ceylon.model.typechecker.model.FunctionOrValue)

Example 10 with TypedReference

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

the class MethodDefinitionBuilder method resultTypeNonWidening.

public MethodDefinitionBuilder resultTypeNonWidening(Type currentType, TypedReference typedRef, Type returnType, int flags) {
    TypedReference nonWideningTypedRef = gen.nonWideningTypeDecl(typedRef, currentType);
    returnType = gen.nonWideningType(typedRef, nonWideningTypedRef);
    return resultType(makeResultType(nonWideningTypedRef.getDeclaration(), returnType, flags), typedRef.getDeclaration());
}
Also used : TypedReference(com.redhat.ceylon.model.typechecker.model.TypedReference)

Aggregations

TypedReference (com.redhat.ceylon.model.typechecker.model.TypedReference)24 Type (com.redhat.ceylon.model.typechecker.model.Type)21 TypeParameter (com.redhat.ceylon.model.typechecker.model.TypeParameter)14 FunctionOrValue (com.redhat.ceylon.model.typechecker.model.FunctionOrValue)12 Value (com.redhat.ceylon.model.typechecker.model.Value)11 Function (com.redhat.ceylon.model.typechecker.model.Function)10 Parameter (com.redhat.ceylon.model.typechecker.model.Parameter)10 JavaBeanValue (com.redhat.ceylon.model.loader.model.JavaBeanValue)8 TypedDeclaration (com.redhat.ceylon.model.typechecker.model.TypedDeclaration)8 ModelUtil.appliedType (com.redhat.ceylon.model.typechecker.model.ModelUtil.appliedType)7 ParameterList (com.redhat.ceylon.model.typechecker.model.ParameterList)7 TypeDeclaration (com.redhat.ceylon.model.typechecker.model.TypeDeclaration)7 JCExpression (com.sun.tools.javac.tree.JCTree.JCExpression)7 ArrayList (java.util.ArrayList)6 Class (com.redhat.ceylon.model.typechecker.model.Class)5 Declaration (com.redhat.ceylon.model.typechecker.model.Declaration)5 JCNewClass (com.sun.tools.javac.tree.JCTree.JCNewClass)5 JCTypeParameter (com.sun.tools.javac.tree.JCTree.JCTypeParameter)5 ThrowerCatchallConstructor (com.redhat.ceylon.compiler.java.codegen.recovery.ThrowerCatchallConstructor)4 AnnotationList (com.redhat.ceylon.compiler.typechecker.tree.Tree.AnnotationList)4