Search in sources :

Example 11 with TypedReference

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

the class ClassTransformer method makeGetterOrSetter.

private AttributeDefinitionBuilder makeGetterOrSetter(Tree.AttributeDeclaration decl, boolean forCompanion, AttributeDefinitionBuilder builder, boolean isGetter) {
    at(decl);
    Value declarationModel = decl.getDeclarationModel();
    boolean withinInterface = declarationModel.isInterfaceMember();
    boolean isStatic = declarationModel.isStatic();
    Tree.SpecifierOrInitializerExpression specOrInit = decl.getSpecifierOrInitializerExpression();
    boolean lazy = specOrInit instanceof Tree.LazySpecifierExpression;
    if (forCompanion || lazy || withinInterface && isStatic) {
        if (specOrInit != null) {
            HasErrorException error = errors().getFirstExpressionErrorAndMarkBrokenness(specOrInit.getExpression());
            if (error != null) {
                builder.getterBlock(make().Block(0, List.<JCStatement>of(makeThrowUnresolvedCompilationError(error))));
            } else {
                TypedReference typedRef = getTypedReference(declarationModel);
                TypedReference nonWideningTypedRef = nonWideningTypeDecl(typedRef);
                Type nonWideningType = nonWideningType(typedRef, nonWideningTypedRef);
                int flags = 0;
                if (declarationModel.hasUncheckedNullType())
                    flags |= ExpressionTransformer.EXPR_TARGET_ACCEPTS_NULL;
                if (CodegenUtil.downcastForSmall(specOrInit.getExpression(), declarationModel))
                    flags |= ExpressionTransformer.EXPR_UNSAFE_PRIMITIVE_TYPECAST_OK;
                JCExpression expr = expressionGen().transformExpression(specOrInit.getExpression(), CodegenUtil.getBoxingStrategy(declarationModel), nonWideningType, flags);
                expr = convertToIntIfHashAttribute(declarationModel, expr);
                builder.getterBlock(make().Block(0, List.<JCStatement>of(make().Return(expr))));
            }
        } else {
            JCExpression accessor = naming.makeQualifiedName(naming.makeQuotedThis(), declarationModel, Naming.NA_MEMBER | (isGetter ? Naming.NA_GETTER : Naming.NA_SETTER));
            if (isGetter) {
                builder.getterBlock(make().Block(0, List.<JCStatement>of(make().Return(make().Apply(null, accessor, List.<JCExpression>nil())))));
            } else {
                List<JCExpression> args = List.<JCExpression>of(naming.makeName(declarationModel, Naming.NA_MEMBER | Naming.NA_IDENT));
                builder.setterBlock(make().Block(0, List.<JCStatement>of(make().Exec(make().Apply(null, accessor, args)))));
            }
        }
    }
    if (forCompanion)
        builder.notActual();
    return builder.modifiers(modifierTransformation().getterSetter(declarationModel, forCompanion)).isFormal(declarationModel.isFormal() || withinInterface && !forCompanion && !isStatic).isJavaNative(declarationModel.isJavaNative());
}
Also used : Type(org.eclipse.ceylon.model.typechecker.model.Type) JCExpression(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression) TypedReference(org.eclipse.ceylon.model.typechecker.model.TypedReference) HasErrorException(org.eclipse.ceylon.compiler.java.codegen.recovery.HasErrorException) Value(org.eclipse.ceylon.model.typechecker.model.Value) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue) JavaBeanValue(org.eclipse.ceylon.model.loader.model.JavaBeanValue) JCPrimitiveTypeTree(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCPrimitiveTypeTree) JCTree(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) JCStatement(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCStatement)

Example 12 with TypedReference

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

the class ClassTransformer method producedTypeParameterBounds.

private java.util.List<java.util.List<Type>> producedTypeParameterBounds(final Reference typedMember, Generic subMethod) {
    java.util.List<java.util.List<Type>> producedTypeParameterBounds = new ArrayList<java.util.List<Type>>(subMethod.getTypeParameters().size());
    for (TypeParameter tp : subMethod.getTypeParameters()) {
        java.util.List<Type> satisfiedTypes = tp.getType().getSatisfiedTypes();
        ArrayList<Type> bounds = new ArrayList<>(satisfiedTypes.size());
        for (Type bound : satisfiedTypes) {
            if (typedMember instanceof Type) {
                bounds.add(bound.substitute((Type) typedMember));
            } else if (typedMember instanceof TypedReference) {
                bounds.add(bound.substitute((TypedReference) typedMember));
            }
        }
        producedTypeParameterBounds.add(bounds);
    }
    return producedTypeParameterBounds;
}
Also used : Type(org.eclipse.ceylon.model.typechecker.model.Type) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) TypedReference(org.eclipse.ceylon.model.typechecker.model.TypedReference) ArrayList(java.util.ArrayList) ArrayList(java.util.ArrayList) AnnotationList(org.eclipse.ceylon.compiler.typechecker.tree.Tree.AnnotationList) List(org.eclipse.ceylon.langtools.tools.javac.util.List) ParameterList(org.eclipse.ceylon.model.typechecker.model.ParameterList)

Example 13 with TypedReference

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

the class ClassTransformer method transform.

public void transform(Tree.AttributeDeclaration decl, ClassDefinitionBuilder classBuilder) {
    final Value model = decl.getDeclarationModel();
    boolean withinInterface = model.isInterfaceMember();
    Tree.SpecifierOrInitializerExpression initializer = decl.getSpecifierOrInitializerExpression();
    final boolean lazy = initializer instanceof Tree.LazySpecifierExpression;
    String attrName = decl.getIdentifier().getText();
    boolean memoized = Decl.isMemoized(decl);
    boolean isStatic = model.isStatic();
    // Only a non-formal or a concrete-non-lazy attribute has a corresponding field
    // and if a captured class parameter exists with the same name we skip this part as well
    Parameter parameter = CodegenUtil.findParamForDecl(decl);
    boolean useField = !lazy && Strategy.useField(model);
    boolean createField = !lazy && !model.isFormal() && Strategy.createField(parameter, model) && !model.isJavaNative();
    boolean createCompanionField = !lazy && withinInterface && initializer != null;
    JCThrow err = null;
    JCExpression memoizedInitialValue = null;
    if (createCompanionField || createField) {
        TypedReference typedRef = getTypedReference(model);
        TypedReference nonWideningTypedRef = nonWideningTypeDecl(typedRef);
        Type nonWideningType = nonWideningType(typedRef, nonWideningTypedRef);
        if (Decl.isIndirect(decl)) {
            attrName = Naming.getAttrClassName(model, 0);
            nonWideningType = getGetterInterfaceType(model);
        }
        JCExpression initialValue = null;
        BoxingStrategy boxingStrategy = null;
        if (initializer != null) {
            Tree.Expression expression = initializer.getExpression();
            HasErrorException error = errors().getFirstExpressionErrorAndMarkBrokenness(expression.getTerm());
            int flags = CodegenUtil.downcastForSmall(expression, model) ? ExpressionTransformer.EXPR_UNSAFE_PRIMITIVE_TYPECAST_OK : 0;
            flags |= model.hasUncheckedNullType() ? ExpressionTransformer.EXPR_TARGET_ACCEPTS_NULL : 0;
            if (error != null) {
                initialValue = null;
                err = makeThrowUnresolvedCompilationError(error.getErrorMessage().getMessage());
            } else {
                boxingStrategy = useJavaBox(model, nonWideningType) && javaBoxExpression(expression.getTypeModel(), nonWideningType) ? BoxingStrategy.JAVA : CodegenUtil.getBoxingStrategy(model);
                initialValue = expressionGen().transformExpression(expression, boxingStrategy, isStatic && nonWideningType.isTypeParameter() ? typeFact().getAnythingType() : nonWideningType, flags);
            }
        }
        if (memoized) {
            memoizedInitialValue = initialValue;
            initialValue = makeDefaultExprForType(nonWideningType);
        }
        int flags = 0;
        if (!CodegenUtil.isUnBoxed(nonWideningTypedRef.getDeclaration())) {
            flags |= JT_NO_PRIMITIVES;
        }
        long modifiers = useField ? modifierTransformation().field(decl) : modifierTransformation().localVar(decl);
        // does it in those cases)
        if (parameter == null || parameter.isHidden()) {
            JCExpression type;
            if (isStatic && nonWideningType.isTypeParameter()) {
                type = make().Type(syms().objectType);
            } else {
                type = makeJavaType(nonWideningType, flags);
            }
            if (createCompanionField) {
                classBuilder.getCompanionBuilder((TypeDeclaration) model.getContainer()).field(modifiers, attrName, type, initialValue, !useField);
            } else {
                List<JCAnnotation> annos = makeAtIgnore().prependList(expressionGen().transformAnnotations(OutputElement.FIELD, decl));
                if (classBuilder.hasDelegatingConstructors()) {
                    annos = annos.prependList(makeAtNoInitCheck());
                }
                // fields should be ignored, they are accessed by the getters
                if (err == null) {
                    // TODO This should really be using AttributeDefinitionBuilder somehow
                    if (useField) {
                        AttributeDefinitionBuilder adb = AttributeDefinitionBuilder.field(this, null, attrName, model, Decl.isIndirect(decl)).fieldAnnotations(annos).fieldNullability(makeNullabilityAnnotations(model)).initialValue(initialValue, boxingStrategy).fieldVisibilityModifiers(modifiers).modifiers(modifiers);
                        classBuilder.defs(adb.buildFields());
                        List<JCStatement> buildInit = adb.buildInit(false);
                        if (!buildInit.isEmpty()) {
                            if (isStatic) {
                                classBuilder.defs(make().Block(STATIC, buildInit));
                            } else {
                                classBuilder.getInitBuilder().init(buildInit);
                            }
                        }
                    } else if (!memoized) {
                        classBuilder.field(modifiers, attrName, type, initialValue, !useField, annos);
                        if (!isEe(model) && model.isLate() && CodegenUtil.needsLateInitField(model, typeFact())) {
                            classBuilder.field(PRIVATE | Flags.VOLATILE | Flags.TRANSIENT, Naming.getInitializationFieldName(attrName), make().Type(syms().booleanType), make().Literal(false), false, makeAtIgnore());
                        }
                    }
                }
            }
        }
        // A shared attribute might be initialized in a for statement, so
        // we might need a def-assignment subst for it
        JCStatement outerSubs = statementGen().openOuterSubstitutionIfNeeded(model, model.getType(), 0);
        if (outerSubs != null) {
            classBuilder.getInitBuilder().init(outerSubs);
        }
    }
    if (useField || withinInterface || lazy) {
        boolean generateInClassOrInterface = !withinInterface || model.isShared() || isStatic;
        boolean generateInCompanionClass = withinInterface && lazy && !isStatic;
        if (generateInClassOrInterface) {
            // Generate getter in main class or interface (when shared)
            at(decl.getType());
            AttributeDefinitionBuilder getter = makeGetter(decl, false, memoizedInitialValue);
            if (err != null) {
                getter.getterBlock(make().Block(0, List.<JCStatement>of(err)));
            }
            classBuilder.attribute(getter);
        }
        if (generateInCompanionClass) {
            Interface container = (Interface) model.getContainer();
            // Generate getter in companion class
            classBuilder.getCompanionBuilder(container).attribute(makeGetter(decl, true, null));
        }
        if (Decl.isVariable(model) || model.isLate()) {
            if (generateInClassOrInterface) {
                // Generate setter in main class or interface (when shared)
                classBuilder.attribute(makeSetter(decl, false, memoizedInitialValue));
            }
            if (generateInCompanionClass) {
                Interface container = (Interface) model.getContainer();
                // Generate setter in companion class
                classBuilder.getCompanionBuilder(container).attribute(makeSetter(decl, true, null));
            }
        }
    }
}
Also used : TypedReference(org.eclipse.ceylon.model.typechecker.model.TypedReference) JCStatement(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCStatement) Type(org.eclipse.ceylon.model.typechecker.model.Type) JCExpression(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression) HasErrorException(org.eclipse.ceylon.compiler.java.codegen.recovery.HasErrorException) Value(org.eclipse.ceylon.model.typechecker.model.Value) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue) JavaBeanValue(org.eclipse.ceylon.model.loader.model.JavaBeanValue) JCPrimitiveTypeTree(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCPrimitiveTypeTree) JCTree(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) Parameter(org.eclipse.ceylon.model.typechecker.model.Parameter) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) JCAnnotation(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCAnnotation) Interface(org.eclipse.ceylon.model.typechecker.model.Interface) ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) LazyInterface(org.eclipse.ceylon.model.loader.model.LazyInterface) JCThrow(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCThrow)

Example 14 with TypedReference

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

the class ClassTransformer method refineMethod.

/*private Class refineClass(
            Scope container,
            Reference pr,
            ClassOrInterface classModel, 
            Class formalClass,
            Unit unit) {
        Class refined = new Class();
        refined.setActual(true);
        refined.setShared(formalClass.isShared());
        refined.setContainer(container);
        refined.setExtendedType(formalClass.getType());
        refined.setDeprecated(formalClass.isDeprecated());
        refined.setName(formalClass.getName());
        refined.setRefinedDeclaration(formalClass.getRefinedDeclaration());
        refined.setScope(container);
        //refined.setType(pr.getType());
        refined.setUnit(unit);
        for (ParameterList formalPl : formalClass.getParameterLists()) {
            ParameterList refinedPl = new ParameterList();
            for (Parameter formalP : formalPl.getParameters()){
                Parameter refinedP = new Parameter();
                refinedP.setAtLeastOne(formalP.isAtLeastOne());
                refinedP.setDeclaration(refined);
                refinedP.setDefaulted(formalP.isDefaulted());
                refinedP.setDeclaredAnything(formalP.isDeclaredAnything());
                refinedP.setHidden(formalP.isHidden());
                refinedP.setSequenced(formalP.isSequenced());
                refinedP.setName(formalP.getName());
                final TypedReference typedParameter = pr.getTypedParameter(formalP);
                FunctionOrValue paramModel;
                if (formalP.getModel() instanceof Value) {
                    Value paramValueModel = refineValue((Value)formalP.getModel(), typedParameter, refined, classModel.getUnit());
                    paramValueModel.setInitializerParameter(refinedP);
                    paramModel = paramValueModel;
                } else {
                    Function paramFunctionModel = refineMethod(refined, typedParameter, classModel, (Function)formalP.getModel(), unit);
                    paramFunctionModel.setInitializerParameter(refinedP);
                    paramModel = paramFunctionModel; 
                }
                refinedP.setModel(paramModel);
                refinedPl.getParameters().add(refinedP);
            }
            refined.addParameterList(refinedPl);
        }
        return refined;
    }*/
private Function refineMethod(Scope container, TypedReference pr, ClassOrInterface classModel, Function formalMethod, Unit unit) {
    Function refined = new Function();
    refined.setActual(true);
    refined.setShared(formalMethod.isShared());
    refined.setContainer(container);
    // in case there are subclasses
    refined.setDefault(true);
    refined.setDeferred(false);
    refined.setDeprecated(formalMethod.isDeprecated());
    refined.setName(formalMethod.getName());
    refined.setRefinedDeclaration(formalMethod.getRefinedDeclaration());
    refined.setScope(container);
    refined.setType(pr.getType());
    refined.setUnit(unit);
    refined.setUnboxed(formalMethod.getUnboxed());
    refined.setUntrustedType(formalMethod.getUntrustedType());
    refined.setTypeErased(formalMethod.getTypeErased());
    ArrayList<TypeParameter> refinedTp = new ArrayList<TypeParameter>();
    ;
    for (TypeParameter formalTp : formalMethod.getTypeParameters()) {
        refinedTp.add(formalTp);
    }
    refined.setTypeParameters(refinedTp);
    for (ParameterList formalPl : formalMethod.getParameterLists()) {
        ParameterList refinedPl = new ParameterList();
        for (Parameter formalP : formalPl.getParameters()) {
            Parameter refinedP = new Parameter();
            refinedP.setAtLeastOne(formalP.isAtLeastOne());
            refinedP.setDeclaration(refined);
            refinedP.setDefaulted(formalP.isDefaulted());
            refinedP.setDeclaredAnything(formalP.isDeclaredAnything());
            refinedP.setHidden(formalP.isHidden());
            refinedP.setSequenced(formalP.isSequenced());
            refinedP.setName(formalP.getName());
            final TypedReference typedParameter = pr.getTypedParameter(formalP);
            FunctionOrValue paramModel;
            if (formalP.getModel() instanceof Value) {
                Value paramValueModel = refineValue((Value) formalP.getModel(), typedParameter, refined, classModel.getUnit());
                paramValueModel.setInitializerParameter(refinedP);
                paramModel = paramValueModel;
            } else {
                Function paramFunctionModel = refineMethod(refined, typedParameter, classModel, (Function) formalP.getModel(), unit);
                paramFunctionModel.setInitializerParameter(refinedP);
                paramModel = paramFunctionModel;
            }
            refinedP.setModel(paramModel);
            refinedPl.getParameters().add(refinedP);
        }
        refined.addParameterList(refinedPl);
    }
    return refined;
}
Also used : Function(org.eclipse.ceylon.model.typechecker.model.Function) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) TypedReference(org.eclipse.ceylon.model.typechecker.model.TypedReference) ArrayList(java.util.ArrayList) Value(org.eclipse.ceylon.model.typechecker.model.Value) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue) JavaBeanValue(org.eclipse.ceylon.model.loader.model.JavaBeanValue) ParameterList(org.eclipse.ceylon.model.typechecker.model.ParameterList) Parameter(org.eclipse.ceylon.model.typechecker.model.Parameter) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)

Example 15 with TypedReference

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

the class ClassTransformer method makeDelegateToCompanion.

/**
 * Generates a method which delegates to the companion instance $Foo$impl
 */
private MethodDefinitionBuilder makeDelegateToCompanion(Interface iface, Reference typedMember, Type currentType, final long mods, final java.util.List<TypeParameter> typeParameters, final java.util.List<java.util.List<Type>> producedTypeParameterBounds, final Type methodType, final String methodName, final java.util.List<Parameter> parameters, boolean typeErased, final String targetMethodName, Parameter defaultedParam, boolean includeBody) {
    final MethodDefinitionBuilder concreteWrapper = MethodDefinitionBuilder.systemMethod(gen(), methodName);
    concreteWrapper.modifiers(mods);
    concreteWrapper.ignoreModelAnnotations();
    if ((mods & PRIVATE) == 0) {
        concreteWrapper.isOverride(true);
    }
    if (typeParameters != null) {
        concreteWrapper.reifiedTypeParametersFromModel(typeParameters);
    }
    Iterator<java.util.List<Type>> iterator = producedTypeParameterBounds.iterator();
    if (typeParameters != null) {
        for (TypeParameter tp : typeParameters) {
            concreteWrapper.typeParameter(tp, iterator.next());
        }
    }
    boolean explicitReturn = false;
    Declaration member = (defaultedParam != null ? typedMember.getTypedParameter(defaultedParam) : typedMember).getDeclaration();
    Type returnType = null;
    if (!isAnything(methodType) || ((member instanceof Function || member instanceof Value) && !Decl.isUnboxedVoid(member)) || (member instanceof Function && Strategy.useBoxedVoid((Function) member))) {
        explicitReturn = true;
        if (CodegenUtil.isHashAttribute(member)) {
            // delegates for hash attributes are int
            concreteWrapper.resultType(new TransformedType(make().Type(syms().intType)));
            returnType = typedMember.getType();
        } else if (typedMember instanceof TypedReference && defaultedParam == null) {
            TypedReference typedRef = (TypedReference) typedMember;
            // This is very much like for method refinement: if the supertype is erased -> go raw.
            // Except for some reason we only need to do it with multiple inheritance with different type
            // arguments, so let's not go overboard
            int flags = 0;
            if (CodegenUtil.hasTypeErased((TypedDeclaration) member.getRefinedDeclaration()) || CodegenUtil.hasTypeErased((TypedDeclaration) member) && isInheritedTwiceWithDifferentTypeArguments(currentType, iface)) {
                flags |= AbstractTransformer.JT_RAW;
            }
            concreteWrapper.resultTypeNonWidening(currentType, typedRef, typedMember.getType(), flags);
            // FIXME: this is redundant with what we computed in the previous line in concreteWrapper.resultTypeNonWidening
            TypedReference nonWideningTypedRef = gen().nonWideningTypeDecl(typedRef, currentType);
            returnType = gen().nonWideningType(typedRef, nonWideningTypedRef);
        } else if (defaultedParam != null) {
            TypedReference typedParameter = typedMember.getTypedParameter(defaultedParam);
            NonWideningParam nonWideningParam = concreteWrapper.getNonWideningParam(typedParameter, currentType.getDeclaration() instanceof Class ? WideningRules.FOR_MIXIN : WideningRules.NONE);
            returnType = nonWideningParam.nonWideningType;
            if (member instanceof Function)
                returnType = typeFact().getCallableType(returnType);
            concreteWrapper.resultType(new TransformedType(makeJavaType(returnType, nonWideningParam.flags)));
        } else {
            concreteWrapper.resultType(new TransformedType(makeJavaType((Type) typedMember)));
            returnType = (Type) typedMember;
        }
    }
    ListBuffer<JCExpression> arguments = new ListBuffer<JCExpression>();
    if (typeParameters != null) {
        for (TypeParameter tp : typeParameters) {
            arguments.add(naming.makeUnquotedIdent(naming.getTypeArgumentDescriptorName(tp)));
        }
    }
    Declaration declaration = typedMember.getDeclaration();
    if (declaration instanceof Constructor && !Decl.isDefaultConstructor((Constructor) declaration) && defaultedParam == null) {
        concreteWrapper.parameter(makeConstructorNameParameter((Constructor) declaration));
        arguments.add(naming.makeUnquotedIdent(Unfix.$name$));
    }
    int ii = 0;
    for (Parameter param : parameters) {
        Parameter parameter;
        if (declaration instanceof Functional) {
            parameter = ((Functional) declaration).getFirstParameterList().getParameters().get(ii++);
        } else if (declaration instanceof Setter) {
            parameter = ((Setter) declaration).getParameter();
        } else {
            throw BugException.unhandledDeclarationCase(declaration);
        }
        final TypedReference typedParameter = typedMember.getTypedParameter(parameter);
        concreteWrapper.parameter(null, param, typedParameter, null, FINAL, WideningRules.FOR_MIXIN);
        arguments.add(naming.makeName(param.getModel(), Naming.NA_MEMBER | Naming.NA_ALIASED));
    }
    if (includeBody) {
        JCExpression qualifierThis = makeUnquotedIdent(getCompanionFieldName(iface));
        // our impl accessor to get the expected bounds of the qualifying type
        if (explicitReturn) {
            Type javaType = getBestSatisfiedType(currentType, iface);
            Type ceylonType = typedMember.getQualifyingType();
            // don't even bother if the impl accessor is turned to raw because casting it to raw doesn't help
            if (!isTurnedToRaw(ceylonType) && // if it's exactly the same we don't need any cast
            !javaType.isExactly(ceylonType))
                // this will add the proper cast to the impl accessor
                qualifierThis = expressionGen().applyErasureAndBoxing(qualifierThis, currentType, false, true, BoxingStrategy.BOXED, ceylonType, ExpressionTransformer.EXPR_WANTS_COMPANION);
        }
        JCExpression expr = make().Apply(// TODO Type args
        null, makeSelect(qualifierThis, (targetMethodName != null) ? targetMethodName : methodName), arguments.toList());
        if (isUnimplementedMemberClass(currentType, typedMember)) {
            concreteWrapper.body(makeThrowUnresolvedCompilationError(// TODO encapsulate the error message
            "formal member '" + declaration.getName() + "' of '" + iface.getName() + "' not implemented in class hierarchy"));
            current().broken();
        } else if (!explicitReturn) {
            concreteWrapper.body(gen().make().Exec(expr));
        } else {
            // deal with erasure and stuff
            BoxingStrategy boxingStrategy;
            boolean exprBoxed;
            if (member instanceof TypedDeclaration) {
                TypedDeclaration typedDecl = (TypedDeclaration) member;
                exprBoxed = !CodegenUtil.isUnBoxed(typedDecl);
                boxingStrategy = CodegenUtil.getBoxingStrategy(typedDecl);
            } else {
                // must be a class or interface
                exprBoxed = true;
                boxingStrategy = BoxingStrategy.UNBOXED;
            }
            // to force an additional cast
            if (isTurnedToRaw(typedMember.getQualifyingType()) || // in invariant locations
            needsRawCastForMixinSuperCall(iface, methodType) || needsCastForErasedInstantiator(iface, methodName, member))
                typeErased = true;
            expr = gen().expressionGen().applyErasureAndBoxing(expr, methodType, typeErased, exprBoxed, boxingStrategy, returnType, 0);
            concreteWrapper.body(gen().make().Return(expr));
        }
    }
    return concreteWrapper;
}
Also used : TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) NonWideningParam(org.eclipse.ceylon.compiler.java.codegen.MethodDefinitionBuilder.NonWideningParam) TypedReference(org.eclipse.ceylon.model.typechecker.model.TypedReference) ThrowerCatchallConstructor(org.eclipse.ceylon.compiler.java.codegen.recovery.ThrowerCatchallConstructor) Constructor(org.eclipse.ceylon.model.typechecker.model.Constructor) ListBuffer(org.eclipse.ceylon.langtools.tools.javac.util.ListBuffer) Functional(org.eclipse.ceylon.model.typechecker.model.Functional) Function(org.eclipse.ceylon.model.typechecker.model.Function) Type(org.eclipse.ceylon.model.typechecker.model.Type) JCExpression(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression) Value(org.eclipse.ceylon.model.typechecker.model.Value) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue) JavaBeanValue(org.eclipse.ceylon.model.loader.model.JavaBeanValue) Setter(org.eclipse.ceylon.model.typechecker.model.Setter) Parameter(org.eclipse.ceylon.model.typechecker.model.Parameter) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) ArrayList(java.util.ArrayList) AnnotationList(org.eclipse.ceylon.compiler.typechecker.tree.Tree.AnnotationList) List(org.eclipse.ceylon.langtools.tools.javac.util.List) ParameterList(org.eclipse.ceylon.model.typechecker.model.ParameterList) Class(org.eclipse.ceylon.model.typechecker.model.Class) JCNewClass(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCNewClass) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) MethodDeclaration(org.eclipse.ceylon.compiler.typechecker.tree.Tree.MethodDeclaration)

Aggregations

TypedReference (org.eclipse.ceylon.model.typechecker.model.TypedReference)40 Type (org.eclipse.ceylon.model.typechecker.model.Type)35 ModelUtil.appliedType (org.eclipse.ceylon.model.typechecker.model.ModelUtil.appliedType)17 TypeParameter (org.eclipse.ceylon.model.typechecker.model.TypeParameter)17 FunctionOrValue (org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)16 Function (org.eclipse.ceylon.model.typechecker.model.Function)15 Value (org.eclipse.ceylon.model.typechecker.model.Value)14 Parameter (org.eclipse.ceylon.model.typechecker.model.Parameter)12 Tree (org.eclipse.ceylon.compiler.typechecker.tree.Tree)11 AnalyzerUtil.getTupleType (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTupleType)10 AnalyzerUtil.spreadType (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.spreadType)10 ModelUtil.intersectionType (org.eclipse.ceylon.model.typechecker.model.ModelUtil.intersectionType)10 TypedDeclaration (org.eclipse.ceylon.model.typechecker.model.TypedDeclaration)10 JCExpression (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression)9 ModelUtil.genericFunctionType (org.eclipse.ceylon.model.typechecker.model.ModelUtil.genericFunctionType)8 ModelUtil.unionType (org.eclipse.ceylon.model.typechecker.model.ModelUtil.unionType)8 ParameterList (org.eclipse.ceylon.model.typechecker.model.ParameterList)8 TypeDeclaration (org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)8 UnknownType (org.eclipse.ceylon.model.typechecker.model.UnknownType)8 ArrayList (java.util.ArrayList)7