Search in sources :

Example 16 with TypedReference

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

the class ClassTransformer method generateInstantiatorDelegate.

private void generateInstantiatorDelegate(ClassDefinitionBuilder classBuilder, Type satisfiedType, Interface iface, Class klass, Constructor ctor, Type currentType, boolean includeBody) {
    Type typeMember = satisfiedType.getTypeMember(klass, klass.getType().getTypeArgumentList());
    if (ctor != null) {
        typeMember = ctor.appliedType(typeMember, Collections.<Type>emptyList());
    }
    java.util.List<TypeParameter> typeParameters = klass.getTypeParameters();
    java.util.List<Parameter> parameters = (ctor != null ? ctor.getParameterLists() : klass.getParameterLists()).get(0).getParameters();
    long flags = PUBLIC;
    if (includeBody)
        flags |= FINAL;
    else
        flags |= ABSTRACT;
    String instantiatorMethodName = naming.getInstantiatorMethodName(klass);
    for (Parameter param : parameters) {
        if (Strategy.hasDefaultParameterValueMethod(param) && !klass.isActual()) {
            final TypedReference typedParameter = typeMember.getTypedParameter(param);
            // If that method has a defaulted parameter, 
            // we need to generate a default value method
            // which also delegates to the $impl
            final MethodDefinitionBuilder defaultValueDelegate = makeDelegateToCompanion(iface, typedParameter, currentType, flags, typeParameters, producedTypeParameterBounds(typeMember, klass), typedParameter.getFullType(), Naming.getDefaultedParamMethodName(ctor != null ? ctor : klass, param), parameters.subList(0, parameters.indexOf(param)), param.getModel().getTypeErased(), null, DelegateType.FOR_DEFAULT_VALUE, includeBody);
            classBuilder.method(defaultValueDelegate);
        }
        if (Strategy.hasDefaultParameterOverload(param)) {
            final MethodDefinitionBuilder overload = makeDelegateToCompanion(iface, typeMember, currentType, flags, typeParameters, producedTypeParameterBounds(typeMember, klass), typeMember.getType(), instantiatorMethodName, parameters.subList(0, parameters.indexOf(param)), false, null, DelegateType.OTHER, includeBody);
            classBuilder.method(overload);
        }
    }
    final MethodDefinitionBuilder overload = makeDelegateToCompanion(iface, typeMember, currentType, flags, typeParameters, producedTypeParameterBounds(typeMember, klass), typeMember.getType(), instantiatorMethodName, parameters, false, null, DelegateType.OTHER, includeBody);
    classBuilder.method(overload);
}
Also used : Type(com.redhat.ceylon.model.typechecker.model.Type) TypeParameter(com.redhat.ceylon.model.typechecker.model.TypeParameter) TypedReference(com.redhat.ceylon.model.typechecker.model.TypedReference) TypeParameter(com.redhat.ceylon.model.typechecker.model.TypeParameter) Parameter(com.redhat.ceylon.model.typechecker.model.Parameter)

Example 17 with TypedReference

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

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, DelegateType delegateType, 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 = 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(null, make().Type(syms().intType));
            returnType = typedMember.getType();
        } else if (typedMember instanceof TypedReference) {
            TypedReference typedRef = (TypedReference) typedMember;
            if (delegateType == DelegateType.OTHER) {
                // 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 {
                // for default value
                NonWideningParam nonWideningParam = concreteWrapper.getNonWideningParam(typedRef, currentType.getDeclaration() instanceof Class ? WideningRules.FOR_MIXIN : WideningRules.NONE);
                returnType = nonWideningParam.nonWideningType;
                if (member instanceof Function)
                    returnType = typeFact().getCallableType(returnType);
                concreteWrapper.resultType(null, makeJavaType(returnType, nonWideningParam.flags));
            }
        } else {
            concreteWrapper.resultType(null, makeJavaType((Type) typedMember));
            returnType = (Type) typedMember;
        }
    }
    ListBuffer<JCExpression> arguments = ListBuffer.<JCExpression>lb();
    if (typeParameters != null) {
        for (TypeParameter tp : typeParameters) {
            arguments.add(naming.makeUnquotedIdent(naming.getTypeArgumentDescriptorName(tp)));
        }
    }
    if (typedMember.getDeclaration() instanceof Constructor && !Decl.isDefaultConstructor((Constructor) typedMember.getDeclaration())) {
        concreteWrapper.parameter(makeConstructorNameParameter((Constructor) typedMember.getDeclaration()));
        arguments.add(naming.makeUnquotedIdent(Unfix.$name$));
    }
    for (Parameter param : parameters) {
        final TypedReference typedParameter = typedMember.getTypedParameter(param);
        concreteWrapper.parameter(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 '" + typedMember.getDeclaration().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(com.redhat.ceylon.model.typechecker.model.TypedDeclaration) TypeParameter(com.redhat.ceylon.model.typechecker.model.TypeParameter) NonWideningParam(com.redhat.ceylon.compiler.java.codegen.MethodDefinitionBuilder.NonWideningParam) 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) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) FunctionOrValue(com.redhat.ceylon.model.typechecker.model.FunctionOrValue) JavaBeanValue(com.redhat.ceylon.model.loader.model.JavaBeanValue) Value(com.redhat.ceylon.model.typechecker.model.Value) TypeParameter(com.redhat.ceylon.model.typechecker.model.TypeParameter) Parameter(com.redhat.ceylon.model.typechecker.model.Parameter) 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) Class(com.redhat.ceylon.model.typechecker.model.Class) JCNewClass(com.sun.tools.javac.tree.JCTree.JCNewClass) 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 18 with TypedReference

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

the class ClassTransformer method refineClass.

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;
}
Also used : Function(com.redhat.ceylon.model.typechecker.model.Function) TypedReference(com.redhat.ceylon.model.typechecker.model.TypedReference) FunctionOrValue(com.redhat.ceylon.model.typechecker.model.FunctionOrValue) JavaBeanValue(com.redhat.ceylon.model.loader.model.JavaBeanValue) 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) Class(com.redhat.ceylon.model.typechecker.model.Class) JCNewClass(com.sun.tools.javac.tree.JCTree.JCNewClass) FunctionOrValue(com.redhat.ceylon.model.typechecker.model.FunctionOrValue)

Example 19 with TypedReference

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

the class ClassTransformer method concreteMembersFromSuperinterfaces.

/**
     * Generates companion fields ($Foo$impl) and methods
     */
private void concreteMembersFromSuperinterfaces(final Class model, ClassDefinitionBuilder classBuilder, Type satisfiedType, Set<Interface> satisfiedInterfaces) {
    satisfiedType = satisfiedType.resolveAliases();
    Interface iface = (Interface) satisfiedType.getDeclaration();
    if (satisfiedInterfaces.contains(iface) || iface.getType().isExactly(typeFact().getIdentifiableDeclaration().getType())) {
        return;
    }
    // then don't instantiate it...
    if (hasImpl(iface)) {
        // ... otherwise for each satisfied interface, 
        // instantiate an instance of the 
        // companion class in the constructor and assign it to a
        // $Interface$impl field
        transformInstantiateCompanions(classBuilder, model, iface, satisfiedType);
    }
    if (!Decl.isCeylon(iface)) {
        // let's not try to implement CMI for Java interfaces
        return;
    }
    // For each super interface
    for (Declaration member : iface.getMembers()) {
        if (member instanceof Class) {
            Class klass = (Class) member;
            final Type typedMember = satisfiedType.getTypeMember(klass, Collections.<Type>emptyList());
            if (Strategy.generateInstantiator(member) && !klass.hasConstructors() && !model.isFormal() && needsCompanionDelegate(model, typedMember) && model.getDirectMember(member.getName(), null, false) == null) {
                // instantiator method implementation
                generateInstantiatorDelegate(classBuilder, satisfiedType, iface, klass, null, model.getType(), !member.isFormal());
            }
            if (klass.hasConstructors()) {
                for (Declaration m : klass.getMembers()) {
                    if (m instanceof Constructor && Strategy.generateInstantiator(m)) {
                        Constructor ctor = (Constructor) m;
                        generateInstantiatorDelegate(classBuilder, satisfiedType, iface, klass, ctor, model.getType(), true);
                    }
                }
            }
        }
        // type aliases are on the $impl class
        if (member instanceof TypeAlias)
            continue;
        if (Strategy.onlyOnCompanion(member)) {
            // (they're just private methods on the $impl)
            continue;
        }
        if (member instanceof Function) {
            Function method = (Function) member;
            final TypedReference typedMember = satisfiedType.getTypedMember(method, Collections.<Type>emptyList());
            Declaration sub = (Declaration) model.getMember(method.getName(), getSignatureIfRequired(typedMember), false, true);
            if (sub instanceof Function) /* && !sub.isAbstraction()*/
            {
                Function subMethod = (Function) sub;
                if (subMethod.getParameterLists().isEmpty()) {
                    continue;
                }
                java.util.List<java.util.List<Type>> producedTypeParameterBounds = producedTypeParameterBounds(typedMember, subMethod);
                //                    final TypedReference refinedTypedMember = model.getType().getTypedMember(subMethod, Collections.<Type>emptyList());
                final java.util.List<TypeParameter> typeParameters = subMethod.getTypeParameters();
                final java.util.List<Parameter> parameters = subMethod.getFirstParameterList().getParameters();
                boolean hasOverloads = false;
                if (!satisfiedInterfaces.contains((Interface) method.getContainer())) {
                    for (Parameter param : parameters) {
                        if (Strategy.hasDefaultParameterValueMethod(param) && CodegenUtil.getTopmostRefinedDeclaration(param.getModel()).getContainer().equals(member)) {
                            final TypedReference typedParameter = typedMember.getTypedParameter(param);
                            // If that method has a defaulted parameter, 
                            // we need to generate a default value method
                            // which also delegates to the $impl
                            final MethodDefinitionBuilder defaultValueDelegate = makeDelegateToCompanion(iface, typedParameter, model.getType(), PUBLIC | FINAL, typeParameters, producedTypeParameterBounds, typedParameter.getFullType(), Naming.getDefaultedParamMethodName(method, param), parameters.subList(0, parameters.indexOf(param)), param.getModel().getTypeErased(), null, DelegateType.FOR_DEFAULT_VALUE);
                            classBuilder.method(defaultValueDelegate);
                        }
                        if (Strategy.hasDefaultParameterOverload(param)) {
                            if ((method.isDefault() || method.isShared() && !method.isFormal()) && Decl.equal(method, subMethod)) {
                                MethodDefinitionBuilder overload = new DefaultedArgumentMethodTyped(new DaoThis((Tree.AnyMethod) null, null), MethodDefinitionBuilder.method(this, subMethod), typedMember, true).makeOverload(subMethod.getFirstParameterList(), param, typeParameters);
                                classBuilder.method(overload);
                            }
                            hasOverloads = true;
                        }
                    }
                }
                // delegating to the $impl instance
                if (needsCompanionDelegate(model, typedMember)) {
                    final MethodDefinitionBuilder concreteMemberDelegate = makeDelegateToCompanion(iface, typedMember, model.getType(), PUBLIC | (method.isDefault() ? 0 : FINAL), typeParameters, producedTypeParameterBounds, typedMember.getType(), naming.selector(method), method.getFirstParameterList().getParameters(), ((Function) member).getTypeErased(), null, DelegateType.OTHER);
                    classBuilder.method(concreteMemberDelegate);
                }
                if (hasOverloads && (method.isDefault() || method.isShared() && !method.isFormal()) && Decl.equal(method, subMethod)) {
                    final MethodDefinitionBuilder canonicalMethod = makeDelegateToCompanion(iface, typedMember, model.getType(), PRIVATE, subMethod.getTypeParameters(), producedTypeParameterBounds, typedMember.getType(), Naming.selector(method, Naming.NA_CANONICAL_METHOD), method.getFirstParameterList().getParameters(), ((Function) member).getTypeErased(), naming.selector(method), DelegateType.OTHER);
                    classBuilder.method(canonicalMethod);
                }
            }
        } else if (member instanceof Value || member instanceof Setter) {
            TypedDeclaration attr = (TypedDeclaration) member;
            final TypedReference typedMember = satisfiedType.getTypedMember(attr, null);
            if (needsCompanionDelegate(model, typedMember)) {
                Setter setter = (member instanceof Setter) ? (Setter) member : null;
                if (member instanceof Value) {
                    if (member instanceof JavaBeanValue) {
                        setter = ((Value) member).getSetter();
                    }
                    final MethodDefinitionBuilder getterDelegate = makeDelegateToCompanion(iface, typedMember, model.getType(), PUBLIC | (attr.isDefault() ? 0 : FINAL), Collections.<TypeParameter>emptyList(), Collections.<java.util.List<Type>>emptyList(), typedMember.getType(), Naming.getGetterName(attr), Collections.<Parameter>emptyList(), attr.getTypeErased(), null, DelegateType.OTHER);
                    classBuilder.method(getterDelegate);
                }
                if (setter != null) {
                    final MethodDefinitionBuilder setterDelegate = makeDelegateToCompanion(iface, satisfiedType.getTypedMember(setter, null), model.getType(), PUBLIC | (setter.getGetter().isDefault() ? 0 : FINAL), Collections.<TypeParameter>emptyList(), Collections.<java.util.List<Type>>emptyList(), typeFact().getAnythingType(), Naming.getSetterName(attr), Collections.<Parameter>singletonList(setter.getParameter()), setter.getTypeErased(), null, DelegateType.OTHER);
                    classBuilder.method(setterDelegate);
                }
                if (Decl.isValue(member) && ((Value) attr).isVariable()) {
                    // $impl to delegate to
                    throw new BugException("assertion failed: " + member.getQualifiedNameString() + " was unexpectedly a variable value");
                }
            }
        } else {
            Reference typedMember = member instanceof TypeDeclaration ? satisfiedType.getTypeMember((TypeDeclaration) member, Collections.<Type>emptyList()) : satisfiedType.getTypedMember((TypedDeclaration) member, Collections.<Type>emptyList());
            if (needsCompanionDelegate(model, typedMember)) {
                throw new BugException("unhandled concrete interface member " + member.getQualifiedNameString() + " " + member.getClass());
            }
        }
    }
    // Add $impl instances for the whole interface hierarchy
    satisfiedInterfaces.add(iface);
    for (Type sat : iface.getSatisfiedTypes()) {
        sat = model.getType().getSupertype(sat.getDeclaration());
        concreteMembersFromSuperinterfaces(model, classBuilder, sat, satisfiedInterfaces);
    }
}
Also used : TypeParameter(com.redhat.ceylon.model.typechecker.model.TypeParameter) TypedReference(com.redhat.ceylon.model.typechecker.model.TypedReference) Function(com.redhat.ceylon.model.typechecker.model.Function) JCPrimitiveTypeTree(com.sun.tools.javac.tree.JCTree.JCPrimitiveTypeTree) JCTree(com.sun.tools.javac.tree.JCTree) Tree(com.redhat.ceylon.compiler.typechecker.tree.Tree) 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) TypedDeclaration(com.redhat.ceylon.model.typechecker.model.TypedDeclaration) ThrowerCatchallConstructor(com.redhat.ceylon.compiler.java.codegen.recovery.ThrowerCatchallConstructor) Constructor(com.redhat.ceylon.model.typechecker.model.Constructor) Reference(com.redhat.ceylon.model.typechecker.model.Reference) TypedReference(com.redhat.ceylon.model.typechecker.model.TypedReference) TypeAlias(com.redhat.ceylon.model.typechecker.model.TypeAlias) 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) JavaBeanValue(com.redhat.ceylon.model.loader.model.JavaBeanValue) TypeDeclaration(com.redhat.ceylon.model.typechecker.model.TypeDeclaration) ClassOrInterface(com.redhat.ceylon.model.typechecker.model.ClassOrInterface) LazyInterface(com.redhat.ceylon.model.loader.model.LazyInterface) Interface(com.redhat.ceylon.model.typechecker.model.Interface)

Example 20 with TypedReference

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

the class ClassTransformer method makeGetterOrSetter.

private AttributeDefinitionBuilder makeGetterOrSetter(Tree.AttributeDeclaration decl, boolean forCompanion, boolean lazy, AttributeDefinitionBuilder builder, boolean isGetter) {
    at(decl);
    if (forCompanion || lazy) {
        SpecifierOrInitializerExpression specOrInit = decl.getSpecifierOrInitializerExpression();
        if (specOrInit != null) {
            HasErrorException error = errors().getFirstExpressionErrorAndMarkBrokenness(specOrInit.getExpression());
            if (error != null) {
                builder.getterBlock(make().Block(0, List.<JCStatement>of(this.makeThrowUnresolvedCompilationError(error))));
            } else {
                Value declarationModel = decl.getDeclarationModel();
                TypedReference typedRef = getTypedReference(declarationModel);
                TypedReference nonWideningTypedRef = nonWideningTypeDecl(typedRef);
                Type nonWideningType = nonWideningType(typedRef, nonWideningTypedRef);
                JCExpression expr = expressionGen().transformExpression(specOrInit.getExpression(), CodegenUtil.getBoxingStrategy(declarationModel), nonWideningType);
                expr = convertToIntIfHashAttribute(declarationModel, expr);
                builder.getterBlock(make().Block(0, List.<JCStatement>of(make().Return(expr))));
            }
        } else {
            JCExpression accessor = naming.makeQualifiedName(naming.makeQuotedThis(), decl.getDeclarationModel(), 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(decl.getDeclarationModel(), 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(transformAttributeGetSetDeclFlags(decl.getDeclarationModel(), forCompanion)).isFormal((Decl.isFormal(decl) || Decl.withinInterface(decl)) && !forCompanion);
}
Also used : Type(com.redhat.ceylon.model.typechecker.model.Type) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) TypedReference(com.redhat.ceylon.model.typechecker.model.TypedReference) HasErrorException(com.redhat.ceylon.compiler.java.codegen.recovery.HasErrorException) FunctionOrValue(com.redhat.ceylon.model.typechecker.model.FunctionOrValue) JavaBeanValue(com.redhat.ceylon.model.loader.model.JavaBeanValue) Value(com.redhat.ceylon.model.typechecker.model.Value) SpecifierOrInitializerExpression(com.redhat.ceylon.compiler.typechecker.tree.Tree.SpecifierOrInitializerExpression) JCStatement(com.sun.tools.javac.tree.JCTree.JCStatement)

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